added overflow for tasks and overflow shadow to all overflows. also
minimum drag distance is now 10px
This commit is contained in:
@@ -1,6 +1,13 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@import "@nuxt/ui";
|
@import "@nuxt/ui";
|
||||||
|
|
||||||
|
.overflow-shadow {
|
||||||
|
overflow-x: auto;
|
||||||
|
position: relative;
|
||||||
|
mask-image: linear-gradient(to right, rgba(0,0,0,1) 90%, rgba(0,0,0,0));
|
||||||
|
-webkit-mask-image: linear-gradient(to right, rgba(0,0,0,1) 90%, rgba(0,0,0,0));
|
||||||
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--ui-primary: #C02942;
|
--ui-primary: #C02942;
|
||||||
--ui-text-dimmed: var(--ui-color-neutral-400);
|
--ui-text-dimmed: var(--ui-color-neutral-400);
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ function submit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
emit('submnitted', {
|
emit('submnitted', {
|
||||||
|
id: props.input.id,
|
||||||
title: form.data.title,
|
title: form.data.title,
|
||||||
description: form.data.description,
|
description: form.data.description,
|
||||||
from: DateTime.fromISO(form.data.from),
|
from: DateTime.fromISO(form.data.from),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UCard class="[&>*]:p-3">
|
<UCard class="[&>*]:p-3 w-full">
|
||||||
<slot />
|
<slot />
|
||||||
</UCard>
|
</UCard>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ function editTodo() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UCard class="flex w-64 h-full">
|
<UCard class="flex w-64 h-full" :ui="{ body: 'w-full' }">
|
||||||
<div class="flex flex-col h-full w-full gap-5">
|
<div class="flex flex-col h-full w-full gap-5">
|
||||||
<header class="flex flex-col gap-2">
|
<header class="flex flex-col gap-2">
|
||||||
<Title1>Calendar</Title1>
|
<Title1>Calendar</Title1>
|
||||||
@@ -120,16 +120,33 @@ function editTodo() {
|
|||||||
<Title1>Todos</Title1>
|
<Title1>Todos</Title1>
|
||||||
<div class="flex gap-2 flex-col">
|
<div class="flex gap-2 flex-col">
|
||||||
<ListItem v-for="todo in todos">
|
<ListItem v-for="todo in todos">
|
||||||
<div class="flex justify-between">
|
<div class="flex w-full gap-4 items-center">
|
||||||
<span>
|
<span class="grow overflow-scroll py-3 overflow-shadow">
|
||||||
{{ todo.title }}
|
{{ todo.title }}
|
||||||
</span>
|
</span>
|
||||||
<div class="flex gap-1">
|
<div class="flex gap-1">
|
||||||
<UButton size="xs" color="neutral" class="flex justify-center" @click="editTodo">
|
<UButton size="xs" color="neutral" class="flex justify-center" @click="editTodo">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pencil"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"></path><path d="m15 5 4 4"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15"
|
||||||
|
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
|
stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pencil">
|
||||||
|
<path
|
||||||
|
d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z">
|
||||||
|
</path>
|
||||||
|
<path d="m15 5 4 4"></path>
|
||||||
|
</svg>
|
||||||
</UButton>
|
</UButton>
|
||||||
<UButton size="xs" class="flex justify-center" color="primary" @click="() => deleteTodo(todo)">
|
<UButton size="xs" class="flex justify-center" color="primary"
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash-2"><path d="M3 6h18"></path><path d="M19 6v14c0 1-2 2-2 2H7c-1 0-2-1-2-2V6"></path><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path><line x1="10" x2="10" y1="11" y2="17"></line><line x1="14" x2="14" y1="11" y2="17"></line></svg>
|
@click="() => deleteTodo(todo)">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15"
|
||||||
|
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
|
stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
class="lucide lucide-trash-2">
|
||||||
|
<path d="M3 6h18"></path>
|
||||||
|
<path d="M19 6v14c0 1-2 2-2 2H7c-1 0-2-1-2-2V6"></path>
|
||||||
|
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"></path>
|
||||||
|
<line x1="10" x2="10" y1="11" y2="17"></line>
|
||||||
|
<line x1="14" x2="14" y1="11" y2="17"></line>
|
||||||
|
</svg>
|
||||||
</UButton>
|
</UButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -157,4 +174,6 @@ function editTodo() {
|
|||||||
</UCard>
|
</UCard>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -132,7 +132,19 @@ function openDeleteModal(event: Event) {
|
|||||||
function deleteEvent() {
|
function deleteEvent() {
|
||||||
if (deleteContext.value === undefined) return
|
if (deleteContext.value === undefined) return
|
||||||
emits('delete', deleteContext.value?.event)
|
emits('delete', deleteContext.value?.event)
|
||||||
events.value = events.value.filter(e => e.title !== deleteContext.value?.event.title)
|
console.log(events.value)
|
||||||
|
events.value = events.value.filter(e => {
|
||||||
|
if (e.id === undefined || deleteContext.value?.event.id === undefined) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.id === deleteContext.value?.event.id) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
deleteModalOpened.value = false
|
deleteModalOpened.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,13 @@ function mouseup(_: MouseEvent) {
|
|||||||
|
|
||||||
const timeFrom = Math.min(endY.value, startY.value) / column.value.offsetHeight
|
const timeFrom = Math.min(endY.value, startY.value) / column.value.offsetHeight
|
||||||
const timeTo = Math.max(endY.value, startY.value) / column.value.offsetHeight
|
const timeTo = Math.max(endY.value, startY.value) / column.value.offsetHeight
|
||||||
|
|
||||||
|
if (timeTo * column.value.offsetHeight - timeFrom * column.value.offsetHeight <= 10) {
|
||||||
|
startY.value = 0
|
||||||
|
endY.value = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
emit('quick-create', props.day, {
|
emit('quick-create', props.day, {
|
||||||
from: timeFrom,
|
from: timeFrom,
|
||||||
to: timeTo
|
to: timeTo
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function dragStart(e: DragEvent) {
|
|||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div>{{ event.event.from.toFormat('HH:mm') }} - {{ event.event.to.toFormat('HH:mm') }}</div>
|
<div>{{ event.event.from.toFormat('HH:mm') }} - {{ event.event.to.toFormat('HH:mm') }}</div>
|
||||||
<div class="overflow-scroll pb-5">
|
<div class="overflow-scroll pb-5 overflow-shadow">
|
||||||
{{ event.event.description }}
|
{{ event.event.description }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Body } from '#components';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import MainContent from '~/components/ui/MainContent.vue';
|
import MainContent from '~/components/ui/MainContent.vue';
|
||||||
@@ -69,7 +68,8 @@ async function deleteTask(id: number) {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="h-screen w-screen p-4 flex flex-row gap-5">
|
<div class="h-screen w-screen p-4 flex flex-row gap-5">
|
||||||
<Sidebar v-if="tasks !== null" :todos="tasks" v-model:date="date" @create-task="postTask" @delete-task="deleteTask"/>
|
<Sidebar v-if="tasks !== null" :todos="tasks" v-model:date="date" @create-task="postTask"
|
||||||
|
@delete-task="deleteTask" />
|
||||||
<MainContent v-if="events !== null" v-model:events="events" v-model:date="date" @create-event="postEvent" />
|
<MainContent v-if="events !== null" v-model:events="events" v-model:date="date" @create-event="postEvent" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ export class Event {
|
|||||||
private static readonly MINUTES_IN_DAY = 24 * 60
|
private static readonly MINUTES_IN_DAY = 24 * 60
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public readonly title: string,
|
public id: number | undefined,
|
||||||
|
public title: string,
|
||||||
public from: DateTime,
|
public from: DateTime,
|
||||||
public to: DateTime,
|
public to: DateTime,
|
||||||
public description: string
|
public description: string
|
||||||
@@ -39,15 +40,28 @@ export class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static fromSimple(event: SimpleEvent): Event {
|
static fromSimple(event: SimpleEvent): Event {
|
||||||
return new Event(event.title, event.from, event.to, event.description)
|
return new Event(
|
||||||
|
event.id,
|
||||||
|
event.title,
|
||||||
|
event.from,
|
||||||
|
event.to,
|
||||||
|
event.description
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromSerializable(event: SerializableEvent) {
|
static fromSerializable(event: SerializableEvent) {
|
||||||
return new Event(event.title, DateTime.fromISO(event.from), DateTime.fromISO(event.to), event.description)
|
return new Event(
|
||||||
|
event.id,
|
||||||
|
event.title,
|
||||||
|
DateTime.fromISO(event.from),
|
||||||
|
DateTime.fromISO(event.to),
|
||||||
|
event.description
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromPercentDimensions(title: string, dimensions: EventDimensions, date: DateTime, description: string): Event {
|
static fromPercentDimensions(id: number | undefined, title: string, dimensions: EventDimensions, date: DateTime, description: string): Event {
|
||||||
return new Event(
|
return new Event(
|
||||||
|
id,
|
||||||
title,
|
title,
|
||||||
date.startOf('day').plus({ minutes: (dimensions.from / 100) * Event.MINUTES_IN_DAY }),
|
date.startOf('day').plus({ minutes: (dimensions.from / 100) * Event.MINUTES_IN_DAY }),
|
||||||
date.startOf('day').plus({ minutes: (dimensions.to / 100) * Event.MINUTES_IN_DAY }),
|
date.startOf('day').plus({ minutes: (dimensions.to / 100) * Event.MINUTES_IN_DAY }),
|
||||||
@@ -55,13 +69,13 @@ export class Event {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromPixelDimensions(title: string, dimensions: EventDimensions, height: number, date: DateTime, description: string): Event {
|
static fromPixelDimensions(id: number | undefined, title: string, dimensions: EventDimensions, height: number, date: DateTime, description: string): Event {
|
||||||
const percentDimensions: EventDimensions = {
|
const percentDimensions: EventDimensions = {
|
||||||
from: dimensions.from * 100 / height,
|
from: dimensions.from * 100 / height,
|
||||||
to: dimensions.to * 100 / height
|
to: dimensions.to * 100 / height
|
||||||
}
|
}
|
||||||
|
|
||||||
return Event.fromPercentDimensions(title, percentDimensions, date, description)
|
return Event.fromPercentDimensions(id, title, percentDimensions, date, description)
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromDraggedEvent(draggedEvent: DraggedEvent, height: number): Event {
|
static fromDraggedEvent(draggedEvent: DraggedEvent, height: number): Event {
|
||||||
@@ -71,6 +85,7 @@ export class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Event.fromPixelDimensions(
|
return Event.fromPixelDimensions(
|
||||||
|
draggedEvent.target.id,
|
||||||
draggedEvent.target.title,
|
draggedEvent.target.title,
|
||||||
pixelDimensions,
|
pixelDimensions,
|
||||||
height,
|
height,
|
||||||
@@ -91,6 +106,7 @@ export class Event {
|
|||||||
|
|
||||||
toSimple(): SimpleEvent {
|
toSimple(): SimpleEvent {
|
||||||
return {
|
return {
|
||||||
|
id: this.id,
|
||||||
title: this.title,
|
title: this.title,
|
||||||
from: this.from,
|
from: this.from,
|
||||||
to: this.to,
|
to: this.to,
|
||||||
@@ -100,6 +116,7 @@ export class Event {
|
|||||||
|
|
||||||
toSerializable(): SerializableEvent {
|
toSerializable(): SerializableEvent {
|
||||||
return {
|
return {
|
||||||
|
id: this.id,
|
||||||
title: this.title,
|
title: this.title,
|
||||||
from: this.from.toISO() ?? '',
|
from: this.from.toISO() ?? '',
|
||||||
to: this.to.toISO() ?? '',
|
to: this.to.toISO() ?? '',
|
||||||
@@ -135,6 +152,7 @@ export type EventDimensions = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type SimpleEvent = {
|
export type SimpleEvent = {
|
||||||
|
id: number | undefined,
|
||||||
title: string,
|
title: string,
|
||||||
from: DateTime,
|
from: DateTime,
|
||||||
to: DateTime
|
to: DateTime
|
||||||
@@ -142,6 +160,7 @@ export type SimpleEvent = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type SerializableEvent = {
|
export type SerializableEvent = {
|
||||||
|
id: number | undefined,
|
||||||
title: string,
|
title: string,
|
||||||
from: string,
|
from: string,
|
||||||
to: string
|
to: string
|
||||||
|
|||||||
Reference in New Issue
Block a user