mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 14:29:34 +00:00
stage(bugfix) fixed calendar events height
This commit is contained in:
commit
b24fefc8d4
23 files changed
+426
-329
No files matched your search
@@ -67,6 +67,19 @@ export default {
|
||||
* Do not prevent propagation to trigger cell mousedown which highlights the cell if not highlighted.
|
||||
*/
|
||||
onMouseDown(e, touch = false) {
|
||||
let targetElement
|
||||
|
||||
if (e.target.nodeName == 'BUTTON') {
|
||||
targetElement = e.target
|
||||
} else if (e.srcElement.nodeName == 'IMG') {
|
||||
targetElement = e.target.parentElement
|
||||
}
|
||||
|
||||
if (targetElement?.classList?.contains('v-btn__content') || e?.target?.nodeName == 'BUTTON') {
|
||||
e.preventDefault()
|
||||
return
|
||||
}
|
||||
|
||||
// Prevent a double mouse down on touch devices.
|
||||
if ("ontouchstart" in window && !touch) return false;
|
||||
const { clickHoldAnEvent, focusAnEvent, resizeAnEvent, dragAnEvent } =
|
||||
|
||||
@@ -22,36 +22,38 @@
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</template>
|
||||
|
||||
<div class="d-flex align-center event-details event-initials-wrapper">
|
||||
<div class="event-initials d-flex justify-center align-center" :style="{ borderColor: eventColor.color }">
|
||||
<small class="text-inherit">{{ props.event.initials }}</small>
|
||||
</div>
|
||||
<small class="event-initials-date text-inherit">{{ props.event.date?.toLocaleDateString('sk-SK') }}</small>
|
||||
</div>
|
||||
|
||||
<div v-if="['subtask'].includes(event.type)" class="d-flex align-center">
|
||||
<v-icon icon="mdi-skull-outline" size="small" />
|
||||
<small v-if="props.event?.subtask.deadline" class="ml-1">{{ deadline }}</small>
|
||||
<v-tooltip v-else text="Deadline z Mastertasku" location="bottom">
|
||||
<template v-slot:activator="{ props }">
|
||||
<small class="cursor-pointer ml-1" v-if="!props.event?.subtask?.deadline" v-bind="props">{{ deadline }}*</small>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</div>
|
||||
|
||||
<div v-if="['office365'].includes(event.type)" class="d-flex align-center mt-1">
|
||||
<v-icon icon="mdi-pin-outline" size="small" />
|
||||
<small v-if="props.event?.subtask.office365_location" :style="{ color: eventColor.color }" class="ml-1">{{ props.event?.subtask.office365_location }}</small>
|
||||
<v-tooltip v-else text="Miesto" location="bottom">
|
||||
<template v-slot:activator="{ props }">
|
||||
<small class="cursor-pointer ml-1" :style="{ color: eventColor.color }" v-if="!props.event?.subtask?.office365_location" v-bind="props">{{ office365_location }}*</small>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="event__footer-wrapper" :style="{ backgroundColor: eventColor.backgroundColor }">
|
||||
<div class="event__footer-wrapper__top">
|
||||
<div class="d-flex align-center event-details event-initials-wrapper">
|
||||
<div class="event-initials d-flex justify-center align-center" :style="{ borderColor: eventColor.color }">
|
||||
<small class="text-inherit">{{ props.event.initials }}</small>
|
||||
</div>
|
||||
<small class="event-initials-date text-inherit">{{ props.event.date?.toLocaleDateString('sk-SK') }}</small>
|
||||
</div>
|
||||
|
||||
<div v-if="['subtask'].includes(event.type)" class="d-flex align-center">
|
||||
<v-icon icon="mdi-skull-outline" size="small" />
|
||||
<small v-if="props.event?.subtask.deadline" class="ml-1">{{ deadline }}</small>
|
||||
<v-tooltip v-else text="Deadline z Mastertasku" location="bottom">
|
||||
<template v-slot:activator="{ props }">
|
||||
<small class="cursor-pointer ml-1" v-if="!props.event?.subtask?.deadline" v-bind="props">{{ deadline }}*</small>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</div>
|
||||
|
||||
<div v-if="['office365'].includes(event.type)" class="d-flex align-center mt-1">
|
||||
<v-icon icon="mdi-pin-outline" size="small" />
|
||||
<small v-if="props.event?.subtask.office365_location" :style="{ color: eventColor.color }" class="ml-1">{{ props.event?.subtask.office365_location }}</small>
|
||||
<v-tooltip v-else text="Miesto" location="bottom">
|
||||
<template v-slot:activator="{ props }">
|
||||
<small class="cursor-pointer ml-1" :style="{ color: eventColor.color }" v-if="!props.event?.subtask?.office365_location" v-bind="props">{{ office365_location }}*</small>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="event__office-footer" v-if="isOfficeEvent">
|
||||
<img :src="office365" alt="" />
|
||||
</div>
|
||||
@@ -62,15 +64,15 @@
|
||||
</template>
|
||||
|
||||
<template v-else-if="event.type == 'adhoc'">
|
||||
<v-btn rounded class="event__footer__button me-2" @click.stop="emits('edit-blocker', props.event)"><img :src="pencil" alt="" /></v-btn>
|
||||
<v-btn rounded class="event__footer__button me-2" @click.stop="emits('delete-blocker', props.event)"><img :src="bin" alt="" /></v-btn>
|
||||
<v-btn rounded class="event__footer__button me-2" @click.stop.prevent="emits('edit-blocker', props.event)"><img :src="pencil" alt="" /></v-btn>
|
||||
<v-btn rounded class="event__footer__button me-2" @click.stop.prevent="emits('delete-blocker', props.event)"><img :src="bin" alt="" /></v-btn>
|
||||
</template>
|
||||
|
||||
<template v-else-if="props.event.type == 'subtask'">
|
||||
<v-btn rounded class="event__footer__button me-2" :class="{ completed: props.event.subtask?.is_finished }" @click.stop="emits('complete-task', props.event)"><img :src="checkmarkDouble" alt="" /></v-btn>
|
||||
<v-btn rounded class="event__footer__button me-2" :class="{ completed: props.event._timeblock_is_finished }" @click.stop="emits('toggle-timeblock-is-finished', props.event)"><img :src="checkmark" alt="" /></v-btn>
|
||||
<v-btn rounded class="event__footer__button me-2" @click.stop="emits('edit-task', props.event)"><img :src="eye" alt="" /></v-btn>
|
||||
<v-btn rounded class="event__footer__button me-2" @click.stop="emits('delete-timeblock-in-task', props.event)"><img :src="bin" alt="" /></v-btn>
|
||||
<v-btn rounded class="event__footer__button me-2" @click.stop.prevent="emits('edit-task', props.event)"><img :src="eye" alt="" /></v-btn>
|
||||
<v-btn rounded class="event__footer__button me-2" @click.stop.prevent="emits('delete-timeblock-in-task', props.event)"><img :src="bin" alt="" /></v-btn>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
@@ -158,6 +160,16 @@ const isOfficeEvent: ComputedRef<boolean> = computed(() => {
|
||||
padding: 20px 10px
|
||||
width: 100%
|
||||
|
||||
&__footer-wrapper
|
||||
position: absolute
|
||||
bottom: 0
|
||||
left: 0
|
||||
right: 0
|
||||
border-top: 1px solid rgba(33, 33, 33, 0.08)
|
||||
|
||||
&__top
|
||||
padding: 10px 10px 0 10px
|
||||
|
||||
&__footer
|
||||
flex-flow: row wrap
|
||||
justify-content: center
|
||||
|
||||
@@ -1,332 +1,396 @@
|
||||
<template>
|
||||
<div class="calendar-wrapper">
|
||||
<Vue-cal
|
||||
:hide-view-selector="true"
|
||||
:hide-title-bar="true"
|
||||
:disable-views="['years', 'year', 'month', 'week']"
|
||||
active-view="day"
|
||||
:selected-date="calConfig.date"
|
||||
:onEventClick="taskClicked"
|
||||
:editable-events="vueCalConfig.editing"
|
||||
:events="calData.tasks"
|
||||
:unscheduledTime="calData.unscheduled_times"
|
||||
:overlaps-per-time-step="false"
|
||||
:showTimeInCells="false"
|
||||
:time-cell-height="timeCellHeight"
|
||||
:snap-to-time="15"
|
||||
:scroll-to-hour="calConfig.scrollHour"
|
||||
:split-days="splits"
|
||||
:sticky-split-labels="true"
|
||||
:min-split-width="140"
|
||||
@ready="onReady()"
|
||||
@view-change="weekChanged"
|
||||
@event-drop="eventMoved"
|
||||
@event-focus="eventFocused"
|
||||
>
|
||||
<template v-slot:split-label="{ split }">
|
||||
<div class="w-[120px] h-100 d-flex flex-column">
|
||||
<span v-if="split.date" class="d-flex align-center">
|
||||
<img v-if="split.isHomeoffice" :src="require('@/plugins/app/_img/icons/home.svg')" class="mr-2">
|
||||
<p class="weekday-label">{{ getHeadingDate(split.date) }}</p>
|
||||
</span>
|
||||
<span v-else class="d-flex align-center">
|
||||
<img v-if="split.isHomeoffice" :src="require('@/plugins/app/_img/icons/home.svg')" class="mr-2">
|
||||
<p class="weekday-label">{{ split.name }}</p>
|
||||
</span>
|
||||
<div class="calendar-wrapper">
|
||||
<Vue-cal
|
||||
:hide-view-selector="true"
|
||||
:hide-title-bar="true"
|
||||
:disable-views="['years', 'year', 'month', 'week']"
|
||||
active-view="day"
|
||||
:selected-date="calConfig.date"
|
||||
:onEventClick="taskClicked"
|
||||
:editable-events="vueCalConfig.editing"
|
||||
:events="calData.tasks"
|
||||
:unscheduledTime="calData.unscheduled_times"
|
||||
:overlaps-per-time-step="false"
|
||||
:showTimeInCells="false"
|
||||
:time-cell-height="timeCellHeight"
|
||||
:snap-to-time="15"
|
||||
:scroll-to-hour="calConfig.scrollHour"
|
||||
:split-days="splits"
|
||||
:sticky-split-labels="true"
|
||||
:min-split-width="140"
|
||||
@ready="onReady()"
|
||||
@view-change="weekChanged"
|
||||
@event-drop="eventMoved"
|
||||
@event-focus="eventFocused"
|
||||
>
|
||||
<template v-slot:split-label="{ split }">
|
||||
<div class="w-[120px] h-100 d-flex flex-column">
|
||||
<span v-if="split.date" class="d-flex align-center">
|
||||
<img
|
||||
v-if="split.isHomeoffice"
|
||||
:src="require('@/plugins/app/_img/icons/home.svg')"
|
||||
class="mr-2"
|
||||
/>
|
||||
<p class="weekday-label">{{ getHeadingDate(split.date) }}</p>
|
||||
</span>
|
||||
<span v-else class="d-flex align-center">
|
||||
<img
|
||||
v-if="split.isHomeoffice"
|
||||
:src="require('@/plugins/app/_img/icons/home.svg')"
|
||||
class="mr-2"
|
||||
/>
|
||||
<p class="weekday-label">{{ split.name }}</p>
|
||||
</span>
|
||||
|
||||
<span v-if="split.date">
|
||||
<p class="day-name" >{{ split.date.toLocaleDateString('en-EN', { weekday: 'long' }) }}</p>
|
||||
</span>
|
||||
<span v-if="split.date">
|
||||
<p class="day-name">
|
||||
{{ split.date.toLocaleDateString('en-EN', { weekday: 'long' }) }}
|
||||
</p>
|
||||
</span>
|
||||
|
||||
<div class="unscheduled-time d-flex align-center text-left" :class="{'vuecal__cell-split--weekend': split.isWeekend}">
|
||||
<div class="unscheduled-time-initials d-flex align-center justify-center">
|
||||
<p>{{ split.initials }}</p>
|
||||
</div>
|
||||
<div class="text-wrap me-4">
|
||||
<p class="mb-0 mt-0 unscheduled-time-name">{{split.fullname}}</p>
|
||||
<h1 class="mb-0 mt-0">{{split.unscheduledTime}} h</h1>
|
||||
<h1 class="mb-0 mt-0" style="font-weight:400;">{{split.scheduledTime}} h</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
class="unscheduled-time d-flex align-center text-left"
|
||||
:class="{ 'vuecal__cell-split--weekend': split.isWeekend }"
|
||||
>
|
||||
<div
|
||||
class="unscheduled-time-initials d-flex align-center justify-center"
|
||||
>
|
||||
<p>{{ split.initials }}</p>
|
||||
</div>
|
||||
<div class="text-wrap me-4">
|
||||
<p class="mb-0 mt-0 unscheduled-time-name">
|
||||
{{ split.fullname }}
|
||||
</p>
|
||||
<h1 class="mb-0 mt-0">{{ split.unscheduledTime }} h</h1>
|
||||
<h1 class="mb-0 mt-0" style="font-weight: 400">
|
||||
{{ split.scheduledTime }} h
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:time-cell="{ hours, minutes }">
|
||||
<span class="d-flex justify-center">
|
||||
<span class="d-flex justify-center">
|
||||
<p style="margin-top: -9px">{{hours}}:{{String(minutes).padStart(2, '0')}}</p>
|
||||
<div class="time-column-line"></div>
|
||||
<span class="vuecal__time-cell-line hour"></span>
|
||||
</span>
|
||||
<template v-slot:time-cell="{ hours, minutes }">
|
||||
<span class="d-flex justify-center">
|
||||
<span class="d-flex justify-center">
|
||||
<p style="margin-top: -9px">
|
||||
{{ hours }}:{{ String(minutes).padStart(2, '0') }}
|
||||
</p>
|
||||
<div class="time-column-line"></div>
|
||||
<span class="vuecal__time-cell-line hour"></span>
|
||||
</span>
|
||||
|
||||
<span class="vuecal__time-cell-line" style="margin-top: 25px"></span>
|
||||
<span class="vuecal__time-cell-line" style="margin-top: 50px"></span>
|
||||
<span class="vuecal__time-cell-line" style="margin-top: 75px"></span>
|
||||
</span>
|
||||
</template>
|
||||
<span class="vuecal__time-cell-line" style="margin-top: 25px"></span>
|
||||
<span class="vuecal__time-cell-line" style="margin-top: 50px"></span>
|
||||
<span class="vuecal__time-cell-line" style="margin-top: 75px"></span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template v-slot:event="{ event }">
|
||||
<A-timeline-event :event="event"
|
||||
@edit-blocker="editBlocker"
|
||||
@delete-blocker="deleteBlocker"
|
||||
@complete-task="completeTask"
|
||||
@toggle-timeblock-is-finished="toggleTimeblockIsFinished"
|
||||
@edit-task="editTask"
|
||||
@delete-timeblock-in-task="deleteTimeBlockInTask"
|
||||
/>
|
||||
</template>
|
||||
</Vue-cal>
|
||||
</div>
|
||||
<template v-slot:event="{ event }">
|
||||
<A-timeline-event
|
||||
:event="event"
|
||||
@edit-blocker="editBlocker"
|
||||
@delete-blocker="deleteBlocker"
|
||||
@complete-task="completeTask"
|
||||
@toggle-timeblock-is-finished="toggleTimeblockIsFinished"
|
||||
@edit-task="editTask"
|
||||
@delete-timeblock-in-task="deleteTimeBlockInTask"
|
||||
/>
|
||||
</template>
|
||||
</Vue-cal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { addDays } from 'date-fns'
|
||||
import tmUtils from '@/plugins/tm@_utils/tm.utils'
|
||||
import { mapGetters } from 'vuex'
|
||||
import moment from 'moment'
|
||||
import ATimelineEvent from './a-timeline-event.vue'
|
||||
import { addDays } from 'date-fns';
|
||||
import tmUtils from '@/plugins/tm@_utils/tm.utils';
|
||||
import { mapGetters } from 'vuex';
|
||||
import moment from 'moment';
|
||||
import ATimelineEvent from './a-timeline-event.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ATimelineEvent,
|
||||
},
|
||||
props: {
|
||||
calData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
calConfig: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default() {
|
||||
return {date: new Date(), scrollHour: 7}
|
||||
}
|
||||
},
|
||||
splits: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ATimelineEvent,
|
||||
},
|
||||
props: {
|
||||
calData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default() {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
calConfig: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default() {
|
||||
return { date: new Date(), scrollHour: 7 };
|
||||
},
|
||||
},
|
||||
splits: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
vueCalConfig: {
|
||||
editing: {
|
||||
title: false,
|
||||
drag: true,
|
||||
resize: false,
|
||||
delete: false,
|
||||
create: false
|
||||
}
|
||||
},
|
||||
focusedEventId: null,
|
||||
timeCellHeight: 100,
|
||||
tmUtils,
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
vueCalConfig: {
|
||||
editing: {
|
||||
title: false,
|
||||
drag: true,
|
||||
resize: false,
|
||||
delete: false,
|
||||
create: false,
|
||||
},
|
||||
},
|
||||
focusedEventId: null,
|
||||
timeCellHeight: 100,
|
||||
tmUtils,
|
||||
visible: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters('tm', ['mastertasks'])
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('tm', ['mastertasks']),
|
||||
},
|
||||
|
||||
methods: {
|
||||
isAfterDeadline(event) {
|
||||
const deadline = this.getDeadline(event.subtask)
|
||||
methods: {
|
||||
isAfterDeadline(event) {
|
||||
const deadline = this.getDeadline(event.subtask);
|
||||
|
||||
if (!deadline)
|
||||
return
|
||||
if (!deadline) return;
|
||||
|
||||
const mDate = moment(event.date)
|
||||
const mDeadline = moment(deadline)
|
||||
const hours = event.end.getHours()
|
||||
const minutes = event.end.getMinutes()
|
||||
const mDate = moment(event.date);
|
||||
const mDeadline = moment(deadline);
|
||||
const hours = event.end.getHours();
|
||||
const minutes = event.end.getMinutes();
|
||||
|
||||
mDate.hours(hours)
|
||||
mDate.minutes(minutes)
|
||||
mDate.hours(hours);
|
||||
mDate.minutes(minutes);
|
||||
|
||||
return mDate.isAfter(mDeadline)
|
||||
},
|
||||
return mDate.isAfter(mDeadline);
|
||||
},
|
||||
|
||||
getDeadline(subtask) {
|
||||
if (subtask?.deadline)
|
||||
return subtask.deadline
|
||||
getDeadline(subtask) {
|
||||
if (subtask?.deadline) return subtask.deadline;
|
||||
|
||||
return subtask.master_task_deadline
|
||||
},
|
||||
return subtask.master_task_deadline;
|
||||
},
|
||||
|
||||
weekChanged() {
|
||||
const scrollContainer = this.$el.getElementsByClassName('vuecal__scrollable-body')[0]
|
||||
scrollContainer.scrollLeft = 0
|
||||
},
|
||||
weekChanged() {
|
||||
const scrollContainer = this.$el.getElementsByClassName(
|
||||
'vuecal__scrollable-body',
|
||||
)[0];
|
||||
scrollContainer.scrollLeft = 0;
|
||||
},
|
||||
|
||||
async eventMoved({ event, newSplit }) {
|
||||
const date = addDays(this.calConfig.date, newSplit - 1)
|
||||
const start = date.setHours(Math.floor(event.startTimeMinutes / 60), Math.round(event.startTimeMinutes % 60), 0)
|
||||
const end = date.setHours(Math.floor(event.endTimeMinutes / 60), Math.round(event.endTimeMinutes % 60), 0)
|
||||
const split = this.splits.find(split => split.id == newSplit )
|
||||
async eventMoved({ event, newSplit }) {
|
||||
const date = addDays(this.calConfig.date, newSplit - 1);
|
||||
const start = date.setHours(
|
||||
Math.floor(event.startTimeMinutes / 60),
|
||||
Math.round(event.startTimeMinutes % 60),
|
||||
0,
|
||||
);
|
||||
const end = date.setHours(
|
||||
Math.floor(event.endTimeMinutes / 60),
|
||||
Math.round(event.endTimeMinutes % 60),
|
||||
0,
|
||||
);
|
||||
const split = this.splits.find((split) => split.id == newSplit);
|
||||
|
||||
if(this.$route.name == 'Dashboard - Tasks') {
|
||||
const editedSubtask = {
|
||||
...event.subtask,
|
||||
timeblocks: [...event.subtask.timeblocks, {
|
||||
id: event._timeblock_id,
|
||||
is_finished: 0,
|
||||
start: tmUtils.formatDateTimeForBackend(start),
|
||||
end: tmUtils.formatDateTimeForBackend(end)
|
||||
}],
|
||||
timesheets: event.subtask.timesheets.map((timesheet) => {
|
||||
delete timesheet.employee_name
|
||||
return timesheet
|
||||
})
|
||||
}
|
||||
if (this.$route.name == 'Dashboard - Tasks') {
|
||||
const editedSubtask = {
|
||||
...event.subtask,
|
||||
timeblocks: [
|
||||
...event.subtask.timeblocks,
|
||||
{
|
||||
id: event._timeblock_id,
|
||||
is_finished: 0,
|
||||
start: tmUtils.formatDateTimeForBackend(start),
|
||||
end: tmUtils.formatDateTimeForBackend(end),
|
||||
},
|
||||
],
|
||||
timesheets: event.subtask.timesheets.map((timesheet) => {
|
||||
delete timesheet.employee_name;
|
||||
return timesheet;
|
||||
}),
|
||||
};
|
||||
|
||||
try {
|
||||
const { subtask } = await this.$axios.put_auth(`v1/subtasks/${editedSubtask.id}`, editedSubtask)
|
||||
this.$events.emit('on-subtask-edited', subtask)
|
||||
try {
|
||||
const { subtask } = await this.$axios.put_auth(
|
||||
`v1/subtasks/${editedSubtask.id}`,
|
||||
editedSubtask,
|
||||
);
|
||||
this.$events.emit('on-subtask-edited', subtask);
|
||||
|
||||
if (subtask.employee_id == this.$store.getters['auth/user'].id)
|
||||
this.$events.emit('show-task-add-time-modal', { subtask })
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message || error)
|
||||
if (subtask.employee_id == this.$store.getters['auth/user'].id)
|
||||
this.$events.emit('show-task-add-time-modal', { subtask });
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message || error);
|
||||
|
||||
if (process.env.NODE_ENV === 'development')
|
||||
console.log('[z-timeline.vue] Error: ', error)
|
||||
}
|
||||
if (process.env.NODE_ENV === 'development')
|
||||
console.log('[z-timeline.vue] Error: ', error);
|
||||
}
|
||||
|
||||
const isAfterDeadline = this.isAfterDeadline(event)
|
||||
const isAfterDeadline = this.isAfterDeadline(event);
|
||||
|
||||
if(isAfterDeadline) this.$toast.error('Timeblock, ktorý ste presunuli je po deadline !')
|
||||
} else if(this.$route.name == 'Dashboard - Teams') {
|
||||
const editedSubtask = {
|
||||
...event.subtask,
|
||||
employee_id: split.employee_id,
|
||||
timeblocks: [...event.subtask.timeblocks, {
|
||||
id: event._timeblock_id,
|
||||
is_finished: 0,
|
||||
start: tmUtils.formatDateTimeForBackend(event.start),
|
||||
end: tmUtils.formatDateTimeForBackend(event.end)
|
||||
}],
|
||||
timesheets: event.subtask.timesheets.map((timesheet) => {
|
||||
delete timesheet.employee_name
|
||||
return timesheet
|
||||
})
|
||||
}
|
||||
try {
|
||||
const { subtask } = await this.$axios.put_auth(`v1/subtasks/${editedSubtask.id}`, editedSubtask)
|
||||
this.$events.emit('on-subtask-edited', subtask)
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message || error)
|
||||
if (isAfterDeadline)
|
||||
this.$toast.error('Timeblock, ktorý ste presunuli je po deadline !');
|
||||
} else if (this.$route.name == 'Dashboard - Teams') {
|
||||
const editedSubtask = {
|
||||
...event.subtask,
|
||||
employee_id: split.employee_id,
|
||||
timeblocks: [
|
||||
...event.subtask.timeblocks,
|
||||
{
|
||||
id: event._timeblock_id,
|
||||
is_finished: 0,
|
||||
start: tmUtils.formatDateTimeForBackend(event.start),
|
||||
end: tmUtils.formatDateTimeForBackend(event.end),
|
||||
},
|
||||
],
|
||||
timesheets: event.subtask.timesheets.map((timesheet) => {
|
||||
delete timesheet.employee_name;
|
||||
return timesheet;
|
||||
}),
|
||||
};
|
||||
try {
|
||||
const { subtask } = await this.$axios.put_auth(
|
||||
`v1/subtasks/${editedSubtask.id}`,
|
||||
editedSubtask,
|
||||
);
|
||||
this.$events.emit('on-subtask-edited', subtask);
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message || error);
|
||||
|
||||
if (process.env.NODE_ENV === 'development')
|
||||
console.log('[z-timeline.vue] Error: ', error)
|
||||
}
|
||||
}
|
||||
},
|
||||
if (process.env.NODE_ENV === 'development')
|
||||
console.log('[z-timeline.vue] Error: ', error);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onReady() {
|
||||
this.correctMargins()
|
||||
},
|
||||
onReady() {
|
||||
this.correctMargins();
|
||||
},
|
||||
|
||||
correctMargins() {
|
||||
if (!this.$el.getElementsByClassName('vuecal__split-days-headers').length)
|
||||
return
|
||||
correctMargins() {
|
||||
if (!this.$el.getElementsByClassName('vuecal__split-days-headers').length)
|
||||
return;
|
||||
|
||||
const heightOfDayHeader = this.$el.getElementsByClassName('vuecal__split-days-headers')[0].clientHeight
|
||||
this.$el.getElementsByClassName('vuecal__time-column')[0].style.marginTop = `${heightOfDayHeader}px`
|
||||
this.$el.getElementsByClassName('vuecal__cells-body')[0].style.marginTop = `${heightOfDayHeader}px`
|
||||
},
|
||||
const heightOfDayHeader = this.$el.getElementsByClassName(
|
||||
'vuecal__split-days-headers',
|
||||
)[0].clientHeight;
|
||||
this.$el.getElementsByClassName(
|
||||
'vuecal__time-column',
|
||||
)[0].style.marginTop = `${heightOfDayHeader}px`;
|
||||
this.$el.getElementsByClassName(
|
||||
'vuecal__cells-body',
|
||||
)[0].style.marginTop = `${heightOfDayHeader}px`;
|
||||
},
|
||||
|
||||
getHeadingDate(value) {
|
||||
const date = new Date(value)
|
||||
getHeadingDate(value) {
|
||||
const date = new Date(value);
|
||||
|
||||
const today = new Date()
|
||||
const yesterday = new Date((new Date()).setDate(today.getDate() - 1))
|
||||
const tomorrow = new Date((new Date()).setDate(today.getDate() + 1))
|
||||
const today = new Date();
|
||||
const yesterday = new Date(new Date().setDate(today.getDate() - 1));
|
||||
const tomorrow = new Date(new Date().setDate(today.getDate() + 1));
|
||||
|
||||
if (today.toLocaleDateString('sk-SK') === date.toLocaleDateString('sk-SK')) return "Dnes"
|
||||
if (yesterday.toLocaleDateString('sk-SK') === date.toLocaleDateString('sk-SK')) return "Včera"
|
||||
if (tomorrow.toLocaleDateString('sk-SK') === date.toLocaleDateString('sk-SK')) return "Zajtra"
|
||||
if (
|
||||
today.toLocaleDateString('sk-SK') === date.toLocaleDateString('sk-SK')
|
||||
)
|
||||
return 'Dnes';
|
||||
if (
|
||||
yesterday.toLocaleDateString('sk-SK') ===
|
||||
date.toLocaleDateString('sk-SK')
|
||||
)
|
||||
return 'Včera';
|
||||
if (
|
||||
tomorrow.toLocaleDateString('sk-SK') ===
|
||||
date.toLocaleDateString('sk-SK')
|
||||
)
|
||||
return 'Zajtra';
|
||||
|
||||
return date.toLocaleDateString('sk-SK')
|
||||
},
|
||||
return date.toLocaleDateString('sk-SK');
|
||||
},
|
||||
|
||||
taskClicked(subtask) {
|
||||
// console.log('task clicked')
|
||||
},
|
||||
taskClicked(subtask) {
|
||||
// console.log('task clicked')
|
||||
},
|
||||
|
||||
eventFocused(event) {
|
||||
this.focusedEventId = event.task_id
|
||||
// console.log(`Focused: ${event.task_id}`)
|
||||
},
|
||||
eventFocused(event) {
|
||||
this.focusedEventId = event.task_id;
|
||||
// console.log(`Focused: ${event.task_id}`)
|
||||
},
|
||||
|
||||
completeTask({ subtask }) {
|
||||
this.$events.emit('show-complete-task-modal', { subtask })
|
||||
},
|
||||
completeTask({ subtask }) {
|
||||
this.$events.emit('show-complete-task-modal', { subtask });
|
||||
},
|
||||
|
||||
// async toggleTimeblockIsFinished(event) {
|
||||
// if (!event.timeblock.is_finished)
|
||||
// this.$events.emit('show-task-add-time-modal', { subtask: event.subtask })
|
||||
// async toggleTimeblockIsFinished(event) {
|
||||
// if (!event.timeblock.is_finished)
|
||||
// this.$events.emit('show-task-add-time-modal', { subtask: event.subtask })
|
||||
|
||||
// try {
|
||||
// await this.$axios.put_auth(`v1/timeblocks/${event._timeblock_id}`, {is_finished: !event.timeblock.is_finished})
|
||||
// // TODO: Co mi to vrati? A updatenut
|
||||
// } catch (error) {
|
||||
// this.$toast.error(error.message || error)
|
||||
// }
|
||||
// },
|
||||
// try {
|
||||
// await this.$axios.put_auth(`v1/timeblocks/${event._timeblock_id}`, {is_finished: !event.timeblock.is_finished})
|
||||
// // TODO: Co mi to vrati? A updatenut
|
||||
// } catch (error) {
|
||||
// this.$toast.error(error.message || error)
|
||||
// }
|
||||
// },
|
||||
|
||||
async toggleTimeblockIsFinished(event) {
|
||||
const subtask = event.subtask
|
||||
const timeblock = subtask.timeblocks.find(originalTimeblock => originalTimeblock.id == event._timeblock_id)
|
||||
async toggleTimeblockIsFinished(event) {
|
||||
const subtask = event.subtask;
|
||||
const timeblock = subtask.timeblocks.find(
|
||||
(originalTimeblock) => originalTimeblock.id == event._timeblock_id,
|
||||
);
|
||||
|
||||
timeblock.is_finished = timeblock?.is_finished ? 0 : 1
|
||||
timeblock.is_finished = timeblock?.is_finished ? 0 : 1;
|
||||
|
||||
try {
|
||||
const {data: newTimeblock} = await this.$axios.put_auth(`v1/timeblocks/${timeblock.id}`, timeblock)
|
||||
try {
|
||||
const { data: newTimeblock } = await this.$axios.put_auth(
|
||||
`v1/timeblocks/${timeblock.id}`,
|
||||
timeblock,
|
||||
);
|
||||
|
||||
subtask.timeblocks = subtask.timeblocks.map(originalTimeblock => {
|
||||
if (originalTimeblock.id == newTimeblock.id)
|
||||
return newTimeblock
|
||||
subtask.timeblocks = subtask.timeblocks.map((originalTimeblock) => {
|
||||
if (originalTimeblock.id == newTimeblock.id) return newTimeblock;
|
||||
|
||||
return originalTimeblock
|
||||
})
|
||||
return originalTimeblock;
|
||||
});
|
||||
|
||||
this.$events.emit('on-subtask-edited', subtask)
|
||||
this.$events.emit('on-subtask-edited', subtask);
|
||||
|
||||
if (timeblock.is_finished)
|
||||
this.$events.emit('show-task-add-time-modal', { subtask })
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message || error)
|
||||
if (timeblock.is_finished)
|
||||
this.$events.emit('show-task-add-time-modal', { subtask });
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message || error);
|
||||
|
||||
if (process.env.NODE_ENV === 'development')
|
||||
console.log('[z-timeline.vue] Error: ', error)
|
||||
}
|
||||
},
|
||||
if (process.env.NODE_ENV === 'development')
|
||||
console.log('[z-timeline.vue] Error: ', error);
|
||||
}
|
||||
},
|
||||
|
||||
editTask({subtask}) {
|
||||
this.$events.emit('show-subtask-modal', {subtask})
|
||||
},
|
||||
editTask({ subtask }) {
|
||||
this.$events.emit('show-subtask-modal', { subtask });
|
||||
},
|
||||
|
||||
deleteTimeBlockInTask({ subtask }) {
|
||||
this.$events.emit('show-delete-timeblock-modal', {subtask})
|
||||
},
|
||||
deleteTimeBlockInTask({ subtask }) {
|
||||
this.$events.emit('show-delete-timeblock-modal', { subtask });
|
||||
},
|
||||
|
||||
editBlocker({ blocker }) {
|
||||
this.$events.emit('show-blocker-modal', {blocker})
|
||||
},
|
||||
editBlocker({ blocker }) {
|
||||
this.$events.emit('show-blocker-modal', { blocker });
|
||||
},
|
||||
|
||||
deleteBlocker({ blocker }) {
|
||||
this.$events.emit('show-delete-blocker-modal', {blocker})
|
||||
},
|
||||
}
|
||||
}
|
||||
deleteBlocker({ blocker }) {
|
||||
this.$events.emit('show-delete-blocker-modal', { blocker });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
@@ -472,6 +536,7 @@ export default {
|
||||
text-align: left
|
||||
background: rgba(248, 248, 248, 1)
|
||||
transition: min-height .4s, height .4s, box-shadow .4s, width .4s, left .4s
|
||||
// border: 1px solid rgba(33, 33, 33, 0.1)
|
||||
|
||||
&:has(.completed)
|
||||
background: rgb(251, 251, 251) !important
|
||||
@@ -483,10 +548,17 @@ export default {
|
||||
|
||||
&.vuecal__event--focus
|
||||
z-index: 100 !important
|
||||
min-height: 350px !important
|
||||
// min-height: 350px !important
|
||||
height: fit-content !important
|
||||
width: 100% !important
|
||||
left: 0 !important
|
||||
|
||||
.event__footer-wrapper
|
||||
position: relative
|
||||
|
||||
&__top
|
||||
padding: 10px 0 0 0
|
||||
|
||||
&:not(.vuecal__event--focus)
|
||||
&:has(.micro-event) .event__body
|
||||
padding: 5px !important
|
||||
@@ -522,7 +594,7 @@ export default {
|
||||
|
||||
.micro-event
|
||||
|
||||
.event__footer
|
||||
.event__footer-wrapper
|
||||
display: none !important
|
||||
|
||||
.project-code
|
||||
|
||||
@@ -447,7 +447,7 @@ export default {
|
||||
},
|
||||
'$route.query': {
|
||||
handler(_, oldValue) {
|
||||
if (oldValue?.subtask?.length) {
|
||||
if (oldValue?.subtask?.length && this.mastertask?.id) {
|
||||
this.loadMastertask(this.mastertask.id);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
v-for="(employee, index) in subtask.employees"
|
||||
:key="`employee-${index}`"
|
||||
class="splitted-inputs remove-employee"
|
||||
:class="{ 'hide-arrow': employee.id }"
|
||||
:class="{ 'hide-arrow': employee?.id }"
|
||||
>
|
||||
<v-autocomplete
|
||||
:custom-filter="customFilter"
|
||||
@@ -854,7 +854,7 @@ export default {
|
||||
|
||||
const lastEmployee =
|
||||
this.subtask.employees[this.subtask.employees.length - 1];
|
||||
if (lastEmployee.id || lastEmployee.duration)
|
||||
if (lastEmployee?.id || lastEmployee?.duration)
|
||||
this.subtask.employees.push({});
|
||||
},
|
||||
deep: true,
|
||||
|
||||
Reference in new issue
Block a user