diff --git a/app/src/plugins/tm@dashboard/_components/a-timeline-event.vue b/app/src/plugins/tm@dashboard/_components/a-timeline-event.vue
index bfd6c42..62cc542 100644
--- a/app/src/plugins/tm@dashboard/_components/a-timeline-event.vue
+++ b/app/src/plugins/tm@dashboard/_components/a-timeline-event.vue
@@ -157,26 +157,30 @@
rounded
class="event__footer__button me-2"
:class="{ completed: props.event.subtask?.is_finished }"
- @click.stop="emits('complete-task', props.event)"
+ @click.stop="handleCompleteTask"
+ @touchend.stop.prevent="handleTouchEnd($event, 'complete-task')"
>
@@ -193,7 +197,7 @@ import {
pencil,
office365,
} from '@/plugins/app/_img';
-import { computed, ComputedRef, defineProps, defineEmits } from 'vue';
+import { computed, ComputedRef } from 'vue';
const props = defineProps<{
event: any;
@@ -208,6 +212,25 @@ const emits = defineEmits<{
(e: 'delete-timeblock-in-task', event: any): void;
}>();
+// iOS: touchend triggers the action (click often doesn't fire on touch devices)
+const handleTouchEnd = (event: TouchEvent, action: string) => {
+ event.preventDefault();
+ event.stopPropagation();
+ if (action === 'complete-task') emits('complete-task', props.event);
+ else if (action === 'toggle-timeblock')
+ emits('toggle-timeblock-is-finished', props.event);
+ else if (action === 'edit-task') emits('edit-task', props.event);
+ else if (action === 'delete-timeblock')
+ emits('delete-timeblock-in-task', props.event);
+};
+
+const handleCompleteTask = () => emits('complete-task', props.event);
+const handleToggleTimeblock = () =>
+ emits('toggle-timeblock-is-finished', props.event);
+const handleEditTask = () => emits('edit-task', props.event);
+const handleDeleteTimeblock = () =>
+ emits('delete-timeblock-in-task', props.event);
+
const deadline: ComputedRef = computed(() => {
if (!props.event.subtask) return undefined;
@@ -308,6 +331,10 @@ const isOfficeEvent: ComputedRef = computed(() => {
&.completed
background: #06dece
+ // Disable pointer events on all child elements so button receives touch events
+ :deep(*)
+ pointer-events: none
+
img
width: 18px