mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 14:29:34 +00:00
Feat(task): Added support for Office 365 events, that are not editable from the application
This commit is contained in:
1 parent
36f992c063
commit
687681865c
48 files changed
+408
-165
No files matched your search
@@ -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 |
@@ -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
|
||||
|
||||
Reference in new issue
Block a user