rough outline of dragging tasks is working

This commit is contained in:
2025-07-06 14:09:27 +02:00
parent 0297fab83b
commit ee19cac4c3
7 changed files with 72 additions and 7 deletions

View File

@@ -7,6 +7,7 @@ import type { DateTime } from 'luxon';
const events = defineModel<Event[]>('events', { required: true })
const date = defineModel<DateTime>('date', { required: true })
const draggedTask = defineModel<DraggedTask | undefined>('draggedTask', { required: true })
const tasks = defineModel<Task[]>('tasks', { required: true })
const emits = defineEmits<{
(e: 'createEvent', event: Event): void
@@ -17,7 +18,7 @@ const emits = defineEmits<{
<template>
<UCard class="flex grow" :ui="{ body: 'w-full h-full' }">
<Calendar @create="(event) => emits('createEvent', event)" v-model:events="events" v-model:date="date" ,
v-model:dragged-task="draggedTask">
v-model:dragged-task="draggedTask" v-model:tasks="tasks">
</Calendar>
</UCard>
</template>

View File

@@ -89,6 +89,7 @@ function cancel() {
<template>
<UModal v-model:open="open" :title="modalTitle" :description="modalDescription">
<template #body>
scheduled at: {{ props.input.scheduled_at }}
<div class="flex flex-col gap-2">
<UInput type="text" placeholder="Name" v-model="titleField" required />
<UInput type="number" class="grow" placeholder="estimated time in hours" v-model="estimatedTimeField"

View File

@@ -7,6 +7,7 @@ import { DateTime } from 'luxon';
import EventFormModal from '../EventFormModal.vue';
const events = defineModel<Event[]>('events', { required: true })
const tasks = defineModel<Task[]>('tasks', { required: true })
const date = defineModel<DateTime>('date', { required: true })
const draggedTask = defineModel<DraggedTask | undefined>('draggedTask', { required: true })
const draggedEvent = ref<DraggedEvent | undefined>()
@@ -35,10 +36,17 @@ function pushEventWithCollisionUpdate(array: CollissionWrapper[], event: Event,
}
}
const taskEvents = computed<Event[]>(() => {
return tasks.value
.filter(task => task.isScheduled())
.map(task => task.toEvent())
})
const days = computed<Day[]>(() => {
return [1, 2, 3, 4, 5, 6, 7].map((i) => {
const eventsToDisplay = [...taskEvents.value, ...events.value]
const currentDate = date.value.startOf('week').plus({ day: i - 1 })
const filteredEvents = events.value.filter(
const filteredEvents = eventsToDisplay.filter(
(event) => event.from >= currentDate.startOf('day') && event.to <= currentDate.endOf('day')
)

View File

@@ -84,6 +84,7 @@ function eventMove(mouseEvent: MouseEvent, event: Event) {
}
function dragover(e: DragEvent) {
e.preventDefault()
drawDraggedEvent(e)
drawDraggedTask(e)
}
@@ -120,7 +121,27 @@ function drawDraggedEvent(event: DragEvent) {
}
function dragDrop(_: DragEvent) {
draggedEvent.value?.target.updateWithDraggedEvent(draggedEvent.value, column.value?.offsetHeight ?? 0)
console.log('dropping')
if (draggedEvent.value !== undefined) {
updateEventWithDraggedEvent()
}
if (draggedTask.value !== undefined) {
console.log('dropping task')
updateTaskWithDraggedTask()
}
}
function updateEventWithDraggedEvent() {
if (draggedEvent.value == undefined) return
if (draggedEvent.value.target.task !== undefined) {
draggedEvent.value.target.task.scheduled_at = draggedEvent.value.date.startOf('day').plus({
minutes: draggedEvent.value.top / (column.value?.offsetHeight ?? 1) * 24 * 60
})
} else {
draggedEvent.value?.target.updateWithDraggedEvent(draggedEvent.value, column.value?.offsetHeight ?? 0)
}
if (draggedEvent.value === undefined) {
draggedEvent.value = undefined
@@ -131,6 +152,22 @@ function dragDrop(_: DragEvent) {
draggedEvent.value = undefined
}
function updateTaskWithDraggedTask() {
if (draggedTask.value === undefined) {
return
}
if (draggedTask.value.dragInfo === undefined) {
return
}
draggedTask.value.target.scheduled_at = draggedTask.value.dragInfo.date.startOf('day').plus({
minutes: draggedTask.value.dragInfo.top / (column.value?.offsetHeight ?? 1) * 24 * 60
})
draggedTask.value = undefined
}
</script>
<template>
@@ -143,7 +180,7 @@ function dragDrop(_: DragEvent) {
</div>
<div id="col" ref="column" @mousedown="mousedown" @mouseup="mouseup" @mousemove="mouseover" @dragover="dragover"
@dragend="dragDrop" class="relative flex flex-col grow items-center select-none">
@dragend="dragDrop" @drop="dragDrop" class="relative flex flex-col grow items-center select-none">
<CalendarSeperator v-for="sep in seperators" :seperator="sep">
<hr class="w-full border-muted">
</CalendarSeperator>
@@ -165,5 +202,5 @@ function dragDrop(_: DragEvent) {
</div>
</template>
<style scoped></style>
<style scoped></style>

View File

@@ -54,7 +54,7 @@ function scheduleTask(task: Task) {
<Sidebar v-if="tasks !== null" v-model:tasks="tasks" v-model:date="date" @create-task="postTask"
@delete-task="deleteTask" @schedule-task="scheduleTask"/>
<MainContent v-if="events !== null" v-model:events="events" v-model:date="date"
v-model:dragged-task="draggedTask" @create-event="postEvent" />
v-model:dragged-task="draggedTask" v-model:tasks="tasks" @create-event="postEvent" />
</div>
</template>

View File

@@ -8,7 +8,8 @@ export class Event {
public title: string,
public from: DateTime,
public to: DateTime,
public description: string
public description: string,
public task: Task | undefined = undefined
) { }
@@ -144,6 +145,10 @@ export class Event {
}
}
isTask() {
return this.task !== undefined
}
}
export type EventDimensions = {

View File

@@ -1,4 +1,5 @@
import { DateTime } from "luxon"
import { Event } from "./event"
export class Task {
constructor(
@@ -43,6 +44,18 @@ export class Task {
isScheduled() {
return this.scheduled_at !== undefined
}
toEvent(): Event {
const scheduledAt = this.scheduled_at ?? DateTime.now()
return new Event(
this.id,
this.title,
scheduledAt,
scheduledAt.plus({ minutes: this.estimated_time }),
this.description,
this
)
}
}
export type SimpleTask = {