Feat(task): Added support for Office 365 events, that are not editable from the application

This commit is contained in:
Matej Glasnák committed 2024-11-06 04:16:52 +01:00
1 parent 36f992c063
commit 687681865c
48 files changed
+408 -165

No files matched your search

+8 -1
View File
@@ -21,6 +21,7 @@
<Z-master-task-modal ref="z-master-task-modal" @master-task-edited="onMasterTaskEdited" />
<Z-delete-team-member-modal ref="z-delete-team-member-modal" />
<Z-show-menu-modal ref="z-show-menu-modal" />
<Z-unable-to-edit-office-task-modal ref="z-unable-to-edit-office-task-modal" />
</template>
<script>
@@ -38,6 +39,7 @@ import ZDeleteMasterTaskModal from '@/plugins/tm@modal/master-task/z-delete-mas
import ZMasterTaskModal from '@/plugins/tm@modal/master-task/z-master-task-modal.vue'
import ZDeleteTeamMemberModal from '@/plugins/tm@modal/master-task/z-delete-team-member-modal.vue'
import ZShowMenuModal from '@/plugins/tm@modal/task-cell/z-show-menu-modal.vue'
import ZUnableToEditOfficeTaskModal from '@/plugins/tm@modal/task/z-unable-to-edit-office-task-modal.vue'
export default {
components: {
@@ -54,7 +56,8 @@ export default {
ZDeleteTeamMemberModal,
ZShowMenuModal,
ZCompleteMasterTaskModal,
ZDeleteTimeBlockModal
ZDeleteTimeBlockModal,
ZUnableToEditOfficeTaskModal
},
mounted() {
@@ -134,6 +137,10 @@ export default {
this.$store.dispatch('tm/reloadMastertasks')
})
this.$events.on('show-unable-to-edit-office-task-modal', ({ subtask }) => {
this.$refs['z-unable-to-edit-office-task-modal'].showModal({ subtask })
})
this._showModalsAfterInicialization()
},
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="943.091" height="211.654" id="office-365">
<g transform="matrix(1.27175 0 0 -1.28344 -60.075 289.533)">
<path fill="#dc3e15" d="M136.488 84.006c.246 1.535.309 112.523.075 114.945-19.032-4.492-38.036-8.98-57.118-13.484l0-78.238C69.621 103.424 59.832 99.635 50.047 95.85c-.063.035-.117.054-.168.09-.043.031-.098.078-.102.121-.031.293-.07.586-.07.883-.004 31.613-.004 63.23-.004 94.765.438.535 1.004.602 1.496.781 27.969 10.379 55.946 20.747 83.918 31.125.969.36 1.848.536 2.922.223 15.348-4.414 30.711-8.777 46.07-13.156.223-.067.446-.145.762-.246l0-133.246c-4.41-1.215-8.781-2.43-13.156-3.625-11.137-3.043-22.281-6.063-33.41-9.129-1.09-.301-2.043-.278-3.114.113-27.511 10.074-55.035 20.117-82.55 30.164-.543.199-1.075.422-1.532.902 28.461-3.871 56.922-7.738 85.379-11.609zM344.594 155.19l-11.696 0 0 9.289 11.215 0c.66.597.473 1.164.473 1.668.019 3.312.008 6.629.012 9.945.004 3.961.668 7.793 2.55 11.324 3.84 7.192 9.899 11.055 18.125 11.52 2.7.152 5.395.043 8.028-.684.453-.125.894-.301 1.394-.473l0-9.613c-.531-.262-.898.16-1.308.321-2.981 1.167-6.035 1.496-9.172.832-2.981-.637-5.215-2.274-6.645-4.969-.902-1.707-1.433-3.535-1.601-5.422-.426-4.719-.129-9.449-.199-14.285l26.785 0c.379.48.234.972.234 1.426.016 3.554-.039 7.109.02 10.66.105 6.285 2.082 11.843 6.695 16.34 3.609 3.511 7.98 5.394 12.984 5.816 2.871.242 5.754.176 8.578-.523.633-.153 1.301-.231 1.848-.723l0-9.668c-1.82.687-3.535 1.332-5.383 1.558-1.875.227-3.718.141-5.531-.304-3.039-.75-5.203-2.59-6.504-5.399-.906-1.961-1.41-4.047-1.461-6.187-.09-4.141-.055-8.289-.066-12.434 0-.164.082-.328.172-.664l15.976 0 0-9.304-16.152 0 0-59.18-11.129 0c-.082 2.765-.027 5.578-.039 8.387-.008 2.781 0 5.566 0 8.347l0 42.34-27.016 0 0-59.07-11.144 0c-.09 2.097-.028 4.258-.039 6.414-.012 2.187-.004 4.379-.004 6.57l0 46.145zM233.621 142.811c.106 9.312 1.535 18.133 5.582 26.402 6.254 12.777 16.551 20.445 30.524 23.32 8.343 1.719 16.707 1.676 24.898-.836 13.383-4.105 22.355-12.91 27.359-25.73 3.231-8.266 4.047-16.887 3.485-25.668-.375-5.812-1.367-11.516-3.41-17.004-5.926-15.941-17.329-25.543-34.305-28.316-9.441-1.543-18.785-.789-27.672 3.058-11.289 4.887-18.695 13.34-22.977 24.625-2.488 6.567-3.421 13.395-3.484 20.149zm80.051 1.582c-.07 1.34-.117 3.293-.277 5.238-.485 5.82-1.696 11.473-4.336 16.742-3.512 7.008-8.766 12.223-16.278 15.008-3.679 1.363-7.508 1.961-11.433 2.043-13.129.273-23.153-5.039-29.856-16.238-3.316-5.539-5.047-11.629-5.601-18-.715-8.164-.02-16.196 3.089-23.899 3.36-8.332 8.899-14.668 17.352-18.258 5.348-2.269 10.957-2.824 16.727-2.324 12.593 1.09 21.511 7.301 26.734 18.641 2.984 6.48 3.777 13.402 3.879 21.047zM715.293 190.881l0-10c-.461-.312-.805.008-1.168.172-3.957 1.801-8.102 2.867-12.457 3.164-7.688.52-14.293-1.762-19.609-7.367-3.797-4.004-6.317-8.75-8.032-13.926-2.148-6.469-2.867-13.156-2.941-20.031.809.148.859.836 1.121 1.289 2.484 4.265 5.785 7.676 10.383 9.742 2.644 1.188 5.426 1.852 8.32 2.039 4.098.266 8.153.039 12.082-1.246 8.063-2.645 13.477-8.078 16.27-15.879 3.086-8.625 2.914-17.355-.492-25.875-4.899-12.258-16.012-19.141-29.582-18.598-9.008.36-16.067 4.223-21.282 11.43-3.582 4.949-5.652 10.531-6.871 16.445-1.687 8.188-1.816 16.45-1.125 24.747.649 7.773 2.297 15.316 5.422 22.511 2.902 6.684 6.918 12.567 12.781 17.098 6.016 4.648 12.871 6.926 20.492 7.023 4.395.051 8.743-.265 13-1.41 1.211-.328 2.407-.711 3.688-1.328zm-43.504-65.234c.063-5.028 1.813-10.965 6.246-15.985 5.707-6.465 14.125-7.258 20.637-4.449 5.344 2.305 8.543 6.582 10.133 11.996 1.691 5.77 1.535 11.59-.344 17.297-1.691 5.145-4.914 9.059-10.168 11.004-3.969 1.465-8.078 1.652-12.188.617-8.585-2.16-14.363-9.855-14.316-20.48zM733.988 144.17c1.09 15.789 2.184 31.707 3.293 47.734l44.891 0 0-9.574c-.008-.011-.035-.062-.078-.097-.043-.039-.098-.075-.153-.09-.113-.035-.23-.074-.347-.074-11.449 0-22.899 0-34.586 0-.731-9.34-1.36-18.622-1.953-27.872.75-.382 1.347-.179 1.925-.164 4.668.133 9.34.446 14-.211 5.981-.847 11.512-2.742 16.266-6.543 4.875-3.894 7.774-8.972 8.863-15.003 1.106-6.082.985-12.168-1.136-18.051-3.16-8.774-9.473-14.465-18.219-17.653-5.492-2.003-11.211-2.367-17-2.207-4.328.118-8.606.551-12.762 1.829-1.375.425-2.695.972-3.972 1.628-.5.258-.891.528-.887 1.192.023 3.539.012 7.082.012 10.719.64.046.988-.309 1.363-.528 4.902-2.886 10.137-4.812 15.851-5.328 4.848-.441 9.606-.051 14.075 1.977 6.929 3.14 10.882 8.468 11.714 16.011.325 2.918.204 5.805-.57 8.629-1.578 5.782-5.363 9.66-10.89 11.938-3.301 1.359-6.774 2.004-10.325 2.125-6.054.199-12.105.07-18.136-.594-.336-.039-.7-.18-1.239.207zM563.445 127.463l-48.828 0c-.211-2.434.215-4.691.676-6.934.691-3.343 1.965-6.453 4.102-9.171 3.378-4.301 7.918-6.594 13.304-7.309 8.84-1.172 16.871.934 24.168 5.934.442.3.895.578 1.348.859.039.027.109.004.18.004.332-.477.168-1.024.175-1.539.016-2.25-.07-4.504.035-6.746.067-1.301-.425-2.035-1.519-2.696-3.563-2.164-7.383-3.648-11.469-4.468-6.164-1.239-12.383-1.578-18.574-.407-10.324 1.961-17.203 8.094-21.141 17.598-1.531 3.699-2.351 7.578-2.707 11.539-.609 6.774-.312 13.481 2.004 19.981 2.981 8.359 7.985 15.093 16.196 19.07 8.121 3.934 16.543 4.16 24.949 1.082 7.316-2.68 11.894-8.141 14.621-15.223 1.57-4Line truncated
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.3 KiB

+23
View File
@@ -0,0 +1,23 @@
import bin from './icons/bin.svg'
import checkmark from './icons/checkmark.svg'
import checkmarkDouble from './icons/checkmark-double.svg'
import eye from './icons/eye.svg'
import home from './icons/home.svg'
import pencil from './icons/pencil.svg'
import previous from './icons/icon-prev.svg'
import next from './icons/icon-next.svg'
import search from './icons/search.svg'
import office365 from './icons/office-365.svg'
export {
bin,
checkmark,
checkmarkDouble,
eye,
home,
pencil,
previous,
next,
search,
office365
}
@@ -334,6 +334,7 @@ export default {
},
draggable() {
const { draggable, background, daysCount } = this.event;
return (
this.vuecal.editEvents.drag &&
draggable &&
@@ -0,0 +1,158 @@
<template>
<div class="event" :class="{ 'event--office': isOfficeEvent }">
<div v-if="props.event.type == 'non-working-hours'" class="custom-event-body non-working-event colWidth 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">{{ props.event.title }}</h3>
</div>
</div>
<div v-else-if="['subtask', 'blocker', 'adhoc', 'vacation', 'free_day'].includes(event.type)" class="custom-event-body colWidth h-100 d-flex flex-column justify-space-between" :class="subtaskCssClass" :style="{ backgroundColor: event._timeblock_is_finished || event.subtask?.is_finished ? '#dedfe0' : event.color || event.subtask?.color }">
<div class="event-content" :class="{ 'is-blocker': props.event.isBlocker }">
<template v-if="props.event.type == 'subtask'">
<small v-if="props.event.subtask.project_code" class="project-code">{{ props.event.subtask.project_code }}</small>
<h3>{{ props.event.subtask.title ?? props.event.subtask.master_task?.name ?? props.event.subtask.master_task }}</h3>
</template>
<template v-else>
<v-tooltip :text="event.blocker?.approved ? 'Schválený' : 'Neschválený'" location="bottom">
<template v-slot:activator="{ props }">
<div v-bind="props">
<h3>{{ props.event.blocker?.approved ? props.event.blocker.name : props.event.blocker.name + '*' }}</h3>
</div>
</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">
<small>{{ props.event.initials }}</small>
</div>
<small class="event-initials-date">{{ props.event.date?.toLocaleDateString('sk-SK') }}</small>
</div>
<div v-if="event.type == 'subtask'" 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>
<div>
<div class="event__office-footer" v-if="isOfficeEvent">
<img :src="office365" alt="" />
</div>
<div class="event__footer d-flex">
<template v-if="isOfficeEvent">
<v-btn rounded class="event__footer__button me-2" @click.stop="editOfficeEvent"><img :src="eye" alt="" /></v-btn>
</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>
</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>
</template>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { bin, checkmarkDouble, checkmark, eye, pencil, office365 } from '@/plugins/app/_img'
import { computed, ComputedRef, defineProps, defineEmits, getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
const props = defineProps<{
event: any // TODO office365: Define type
}>()
const emits = defineEmits<{
(e: 'edit-blocker', event: any): void,
(e: 'delete-blocker', event: any): void,
(e: 'complete-task', event: any): void,
(e: 'toggle-timeblock-is-finished', event: any): void,
(e: 'edit-task', event: any): void,
(e: 'delete-timeblock-in-task', event: any): void
}>()
const deadline: ComputedRef<string | undefined> = computed(() => {
if (!props.event.subtask)
return undefined
if (props.event.subtask.deadline)
return props.event.subtask.deadline
return props.event.subtask.master_task_deadline
})
const eventLength: ComputedRef<number> = computed(() => props.event.end.getTime() - props.event.start.getTime())
const subtaskCssClass: ComputedRef<string> = computed(() => {
const classes = []
if (eventLength.value <= 9000000) classes.push('short-event')
if (eventLength.value <= 5400000) classes.push('mini-event')
if (eventLength.value <= 3600000) classes.push('micro-event')
if (!props.event.blocker?.approved && props.event.isBlocker) classes.push('not-approved')
return classes.join(' ')
})
const isOfficeEvent: ComputedRef<boolean> = computed(() => {
return true
})
const editOfficeEvent = () => {
const eventBus = instance?.appContext.config.globalProperties.$events
eventBus.emit('show-unable-to-edit-office-task-modal', props.event)
}
</script>
<style lang="sass" scoped>
.event
height: 100%
&__office-footer
padding: 5px 15px
img
height: 19px
user-select: none
.custom-event-body
padding: 20px 10px
width: 100%
&__footer
flex-flow: row wrap
justify-content: center
alight-items: center
padding-top: 15px
border-top: 1px solid rgba(33, 33, 33, 0.08)
&__button
box-shadow: none !important
margin-bottom: 8px
padding: 9px !important
min-height: fit-content
height: fit-content
min-width: fit-content
width: fit-content
&.completed
background: #06dece
img
width: 18px
</style>
@@ -24,7 +24,7 @@
@event-focus="eventFocused"
>
<template v-slot:split-label="{ split }">
<div class="colWidth h-100 d-flex flex-column">
<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>
@@ -65,62 +65,14 @@
</template>
<template v-slot:event="{ event }">
<div v-if="event.type == 'non-working-hours'" class="custom-event-body non-working-event colWidth 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-if="['subtask', 'blocker', 'adhoc', 'vacation', 'free_day'].includes(event.type)" class="custom-event-body colWidth h-100 d-flex flex-column justify-space-between" :class="{'short-event' : getEventLength(event) <= 9000000, 'mini-event' : getEventLength(event) <= 5400000, 'micro-event' : getEventLength(event) <= 3600000, 'not-approved': !event.blocker?.approved && event.isBlocker }" :style="{backgroundColor: event._timeblock_is_finished || event.subtask?.is_finished ? '#dedfe0' : event.color || event.subtask?.color}">
<div class="event-content" :class="{'is-blocker': event.isBlocker}">
<template v-if="event.type == 'subtask'">
<small v-if="event.subtask.project_code" class="project-code">{{ event.subtask.project_code }}</small>
<h3>{{ event.subtask.title ?? event.subtask.master_task?.name ?? event.subtask.master_task }}</h3>
</template>
<template v-else>
<v-tooltip :text="event.blocker?.approved ? 'Schválený' : 'Neschválený'" location="bottom">
<template v-slot:activator="{ props }">
<div v-bind="props">
<h3>{{ event.blocker?.approved ? event.blocker.name : (event.blocker.name + '*') }}</h3>
</div>
</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">
<small>{{ event.initials }}</small>
</div>
<small class="event-initials-date">{{ event.date?.toLocaleDateString('sk-SK') }}</small>
</div>
<div v-if="event.type == 'subtask'" class="d-flex align-center">
<v-icon icon="mdi-skull-outline" size="small" />
<small v-if="event?.subtask.deadline" class="ml-1">{{ getDeadline(event?.subtask) }}</small>
<v-tooltip v-else text="Deadline z Mastertasku" location="bottom">
<template v-slot:activator="{ props }">
<small class="cursor-pointer ml-1" v-if="!event?.subtask?.deadline" v-bind="props">{{ getDeadline(event?.subtask) }}*</small>
</template>
</v-tooltip>
</div>
</div>
<div class="event-footer d-flex">
<template v-if="event.type == 'adhoc'">
<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>
<template v-else-if="event.type == 'subtask'">
<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-double.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" :class="{'completed': event._timeblock_is_finished}" @click.stop="toggleTimeblockIsFinished(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="deleteTimeBlockInTask(event)"><img :src="require('@/plugins/app/_img/icons/bin.svg')" alt=""></v-btn>
</template>
</div>
</div>
<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>
@@ -131,8 +83,12 @@ 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,
@@ -300,10 +256,6 @@ export default {
return date.toLocaleDateString('sk-SK')
},
getEventLength(event) {
return event.end.getTime() - event.start.getTime()
},
taskClicked(subtask) {
// console.log('task clicked')
},
@@ -377,12 +329,6 @@ export default {
</script>
<style lang="sass" scoped>
.colWidth
width: 120px
// @media (min-width: 1476px)
// width: 100% !important
.vuecal
box-shadow: none !important
@@ -526,26 +472,11 @@ export default {
background: rgba(248, 248, 248, 1)
transition: min-height .4s, height .4s, box-shadow .4s, width .4s, left .4s
.custom-event-body
padding: 20px 10px
width: 100%
.event-content
&.is-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
&:has(.non-working-event)
&:has(.event__body--non-working-hours)
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)
border: 1px solid rgba(215, 215, 215, 1)
@@ -556,10 +487,10 @@ export default {
left: 0 !important
&:not(.vuecal__event--focus)
&:has(.micro-event) .custom-event-body
&:has(.micro-event) .event__body
padding: 5px !important
&:has(.short-event) .custom-event-body:not(.micro-event)
&:has(.short-event) .event__body:not(.micro-event)
padding: 10px 5px !important
.short-event
.project-code
@@ -570,15 +501,10 @@ export default {
.mini-event
.event-content
// display: flex
// align-items: center
// flex-wrap: nowrap
// justify-content: space-between
width: 100%
padding: 5px 10px
.event-initials-wrapper
// margin-bottom: 0
.event-initials
margin-right: 0
@@ -595,7 +521,7 @@ export default {
.micro-event
.event-footer
.event__footer
display: none !important
.project-code
@@ -626,28 +552,6 @@ export default {
small
font-size: 11px
.event-footer
flex-flow: row wrap
justify-content: center
alight-items: center
padding-top: 15px
border-top: 1px solid rgba(33, 33, 33, 0.08)
.event-footer-button
box-shadow: none !important
margin-bottom: 8px
padding: 9px !important
min-height: fit-content
height: fit-content
min-width: fit-content
width: fit-content
&.completed
background: #06dece
img
width: 18px
.not-approved
background: repeating-linear-gradient(135deg, rgb(215, 215, 215), rgb(215, 215, 215) 1px, rgb(224, 224, 224) 1px, rgb(224, 224, 224) 20px) !important
</style>
@@ -64,7 +64,8 @@ export default {
_timeblock_id: timeblock.id,
_timeblock_is_finished: timeblock.is_finished,
_real_start: new Date(timeblock.start),
_real_end: new Date(timeblock.end)
_real_end: new Date(timeblock.end),
draggable: false // TODO office365: Disable only for office 365 events
}
},
@@ -15,11 +15,19 @@
<p v-if="!subtask.is_finished">Neukončený</p>
</td>
<td class="task-action">
<div class="d-flex justify-start">
<img v-if="subtask.is_finished" class="pencil-icon is-finished" :src="require('@/plugins/app/_img/icons/checkmark.svg')" alt="checkmark-icon" @click.stop="clickCompleteTask(subtask)" />
<img v-if="!subtask.is_finished" class="pencil-icon" :src="require('@/plugins/app/_img/icons/checkmark.svg')" alt="checkmark-icon" @click.stop="clickCompleteTask(subtask)" />
<img class="pencil-icon ml-2" :src="require('@/plugins/app/_img/icons/eye.svg')" alt="pencil-icon" @click.stop="openTaskModal(subtask)" />
<img class="trash-icon" :src="require('@/plugins/app/_img/icons/bin.svg')" alt="trash-icon" @click.stop="openDeleteTaskModal(subtask)" />
<div class="d-flex justify-start align-center">
<!-- TODO office365: Only for office365 events -->
<template v-if="true">
<img class="pencil-icon ml-2" :src="eye" alt="pencil-icon" @click.stop="openTaskModal(subtask)" />
<img class="office-icon" :src="office365" />
</template>
<template v-else>
<img v-if="subtask.is_finished" class="pencil-icon is-finished" :src="checkmark" alt="checkmark-icon" @click.stop="clickCompleteTask(subtask)" />
<img v-if="!subtask.is_finished" class="pencil-icon" :src="checkmark" alt="checkmark-icon" @click.stop="clickCompleteTask(subtask)" />
<img class="pencil-icon ml-2" :src="eye" alt="pencil-icon" @click.stop="openTaskModal(subtask)" />
<img class="trash-icon" :src="bin" alt="trash-icon" @click.stop="openDeleteTaskModal(subtask)" />
</template>
</div>
</td>
</tr>
@@ -29,6 +37,8 @@
<script>
import { mapGetters } from 'vuex'
import { bin, eye, office365, checkmark } from '@/plugins/app/_img'
export default {
props: {
@@ -38,6 +48,15 @@ export default {
}
},
data() {
return {
checkmark,
bin,
eye,
office365
}
},
computed: {
...mapGetters('tm', ['enrichedEmployees']),
@@ -60,11 +79,18 @@ export default {
},
openTaskModal(subtask) {
this.$events.emit('show-subtask-modal', { subtask, editMode: false })
// TODO office365: Only for office365 events
return this.editOfficeEvent(subtask)
// this.$events.emit('show-subtask-modal', { subtask, editMode: false })
},
async clickCompleteTask(subtask) {
this.$events.emit('show-complete-task-modal', { subtask })
},
editOfficeEvent(subtask) {
this.$events.emit('show-unable-to-edit-office-task-modal', { subtask })
}
}
}
@@ -78,6 +104,10 @@ v-table, tbody
td:not(:last-child)
border-right: thin solid rgba(var(--v-border-color), var(--v-border-opacity))
.office-icon
height: 20px
margin-left: 12px
.line-clamp
display: -webkit-box
-webkit-line-clamp: 2
@@ -0,0 +1,47 @@
<template>
<v-dialog v-model="visible" max-width="750" persistent>
<v-card>
<div class="d-flex justify-space-between align-center">
<h1>Sub Task zosynchronizovaný z Office365 sa nedá upravovat. Upravte ho vo svojom kalendári a pockajte
na zosynchronizovanie s Task Managerom</h1>
<v-icon
@click.stop="closeModal()"
icon="mdi-close"
size="large"
></v-icon>
</div>
</v-card>
</v-dialog>
</template>
<script>
import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin'
export default {
mixins: [ modalMixin ],
emits: ['close', 'on-subtask-edited'],
data() {
return {
visible: false,
subtask: null
}
},
methods: {
async showModal({ subtask }) {
this.subtask = subtask
this.visible = true
},
async complete() {
console.log('complete')
},
closeModal() {
this.visible = false
}
}
}
</script>
@@ -25,11 +25,19 @@
<td>{{ displayTimeblock(subtask) }}</td>
<td>{{ subtask.duration }} h</td>
<td>{{ (subtask.duration - subtask.spent_time).toFixed(2) }} h</td>
<td class="task-action">
<div class="d-flex justify-start">
<img class="pencil-icon" :src="require('@/plugins/app/_img/icons/eye.svg')" alt="pencil-icon" @click.stop="editTask(subtask, false)">
<!-- <img class="pencil-icon" :src="require('@/plugins/app/_img/icons/pencil.svg')" alt="pencil-icon" @click.stop="editTask(subtask, true)" /> -->
<img class="trash-icon" :src="require('@/plugins/app/_img/icons/bin.svg')" alt="trash-icon" @click.stop="deleteTask(subtask)" />
<div class="d-flex justify-start align-center">
<!-- TODO office365: Only for office365 events -->
<template v-if="true">
<img class="pencil-icon" :src="eye" @click.stop="editOfficeEvent(subtask)">
<img class="office-icon" :src="office365" />
</template>
<template v-else>
<img class="pencil-icon" :src="eye" @click.stop="editTask(subtask, false)">
<img class="trash-icon" :src="bin" @click.stop="deleteTask(subtask)" />
</template>
</div>
</td>
</tr>
@@ -40,6 +48,8 @@
</template>
<script>
import { bin, eye, office365 } from '@/plugins/app/_img'
import { mapGetters } from 'vuex'
import moment from 'moment'
@@ -51,13 +61,24 @@ export default {
}
},
data() {
return {
eye,
bin,
office365
}
},
computed: {
...mapGetters('tm', ['mastertasks'])
},
methods: {
editTask(subtask, editMode = false) {
this.$events.emit('show-subtask-modal', {subtask, editMode})
// TODO office365: Only for office365 events
return this.editOfficeEvent(subtask)
// this.$events.emit('show-subtask-modal', {subtask, editMode})
},
deleteTask(subtask) {
@@ -90,6 +111,10 @@ export default {
const timeblockDeadline = this.getSelectedTimeblockDeadline(subtask.timeblocks)
return timeblockDeadline !== '' ? timeblockDeadline : 'Žiadny termín'
},
editOfficeEvent(subtask) {
this.$events.emit('show-unable-to-edit-office-task-modal', { subtask })
}
}
}
@@ -99,6 +124,10 @@ export default {
v-table, th, td
border: thin solid rgba(var(--v-border-color), var(--v-border-opacity))
.office-icon
height: 20px
margin-left: 12px
@media screen and (max-width: 496px)
.task-action
div
@@ -23,10 +23,18 @@
</v-tooltip>
<td>{{ subtask.spent_time }} h</td>
<td class="task-action">
<div class="d-flex justify-start">
<img class="pencil-icon" :src="require('@/plugins/app/_img/icons/eye.svg')" alt="pencil-icon" @click.stop="editTask(subtask, false)">
<!-- <img class="pencil-icon" :src="require('@/plugins/app/_img/icons/pencil.svg')" alt="pencil-icon" @click.stop="editTask(subtask, true)"> -->
<img class="trash-icon" :src="require('@/plugins/app/_img/icons/bin.svg')" alt="trash-icon" @click.stop="deleteTask(subtask)">
<div class="d-flex justify-start align-center">
<!-- TODO office365: Only for office365 events -->
<template v-if="true">
<img class="pencil-icon" :src="eye" alt="pencil-icon" @click.stop="editTask(subtask, false)">
<img class="office-icon" :src="office365" alt="office-icon" />
</template>
<template v-else>
<img class="pencil-icon" :src="eye" alt="pencil-icon" @click.stop="editTask(subtask, false)">
<!-- <img class="pencil-icon" :src="require('@/plugins/app/_img/icons/pencil.svg')" alt="pencil-icon" @click.stop="editTask(subtask, true)"> -->
<img class="trash-icon" :src="bin" alt="trash-icon" @click.stop="deleteTask(subtask)">
</template>
</div>
</td>
</tr>
@@ -37,6 +45,7 @@
<script>
import moment from 'moment'
import { mapGetters } from 'vuex'
import { bin, eye, office365 } from '@/plugins/app/_img'
export default {
props: {
@@ -46,13 +55,24 @@ export default {
}
},
data() {
return {
bin,
eye,
office365
}
},
computed: {
...mapGetters('tm', ['mastertasks'])
},
methods: {
editTask(subtask, editMode) {
this.$events.emit('show-subtask-modal', {subtask, editMode})
// TODO office365: Only for office365 events
return this.editOfficeEvent(subtask)
// this.$events.emit('show-subtask-modal', {subtask, editMode})
},
deleteTask(subtask) {
@@ -64,6 +84,10 @@ export default {
return moment(subtask.deadline).format('DD.MM.yyyy')
return moment(subtask.master_task_deadline).format('DD.MM.yyyy')
},
editOfficeEvent(subtask) {
this.$events.emit('show-unable-to-edit-office-task-modal', { subtask })
}
}
}
@@ -73,6 +97,10 @@ export default {
v-table, th, td
border: thin solid rgba(var(--v-border-color), var(--v-border-opacity))
.office-icon
height: 20px
margin-left: 12px
@media screen and (max-width: 379px)
.task-action
div
+8 -3
View File
@@ -1,6 +1,11 @@
/* eslint-disable */
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
declare module '*.svg' {
const content: string
export default content
}