Add all-day event functionality to CalendarView: Introduce a new section for displaying all-day events in both week and day views. Update localization files to include translations for 'All Day' in English and German. Enhance event handling methods to support all-day events, improving the overall calendar experience.
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
"selectedDays": "{count} Tage ausgewählt",
|
"selectedDays": "{count} Tage ausgewählt",
|
||||||
"createEventForSelection": "Termin erstellen",
|
"createEventForSelection": "Termin erstellen",
|
||||||
"clearSelection": "Auswahl aufheben",
|
"clearSelection": "Auswahl aufheben",
|
||||||
|
"allDay": "Ganztägig",
|
||||||
"views": {
|
"views": {
|
||||||
"month": "Monat",
|
"month": "Monat",
|
||||||
"week": "Woche",
|
"week": "Woche",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
"selectedDays": "{count} days selected",
|
"selectedDays": "{count} days selected",
|
||||||
"createEventForSelection": "Create Event",
|
"createEventForSelection": "Create Event",
|
||||||
"clearSelection": "Clear Selection",
|
"clearSelection": "Clear Selection",
|
||||||
|
"allDay": "All Day",
|
||||||
"views": {
|
"views": {
|
||||||
"month": "Month",
|
"month": "Month",
|
||||||
"week": "Week",
|
"week": "Week",
|
||||||
|
|||||||
@@ -87,6 +87,23 @@
|
|||||||
<div :class="['day-date', { today: day.isToday }]">{{ day.dayNumber }}</div>
|
<div :class="['day-date', { today: day.isToday }]">{{ day.dayNumber }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- All-day events row -->
|
||||||
|
<div v-if="hasAnyAllDayEvents(weekDaysData)" class="all-day-row">
|
||||||
|
<div class="all-day-label">{{ $t('personal.calendar.allDay') }}</div>
|
||||||
|
<div class="all-day-events">
|
||||||
|
<div v-for="day in weekDaysData" :key="day.date" class="all-day-cell">
|
||||||
|
<div
|
||||||
|
v-for="event in getEventsForDateAllDay(day.date)"
|
||||||
|
:key="event.id"
|
||||||
|
class="all-day-event"
|
||||||
|
:style="{ backgroundColor: getCategoryColor(event.categoryId) }"
|
||||||
|
@click="editEvent(event)"
|
||||||
|
>
|
||||||
|
{{ event.title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="time-slots-container">
|
<div class="time-slots-container">
|
||||||
<div class="time-labels">
|
<div class="time-labels">
|
||||||
<div v-for="hour in hours" :key="hour" class="time-label">
|
<div v-for="hour in hours" :key="hour" class="time-label">
|
||||||
@@ -127,6 +144,23 @@
|
|||||||
<div :class="['day-date', { today: day.isToday }]">{{ day.dayNumber }}</div>
|
<div :class="['day-date', { today: day.isToday }]">{{ day.dayNumber }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- All-day events row -->
|
||||||
|
<div v-if="hasAnyAllDayEvents(workWeekDaysData)" class="all-day-row">
|
||||||
|
<div class="all-day-label">{{ $t('personal.calendar.allDay') }}</div>
|
||||||
|
<div class="all-day-events">
|
||||||
|
<div v-for="day in workWeekDaysData" :key="day.date" class="all-day-cell">
|
||||||
|
<div
|
||||||
|
v-for="event in getEventsForDateAllDay(day.date)"
|
||||||
|
:key="event.id"
|
||||||
|
class="all-day-event"
|
||||||
|
:style="{ backgroundColor: getCategoryColor(event.categoryId) }"
|
||||||
|
@click="editEvent(event)"
|
||||||
|
>
|
||||||
|
{{ event.title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="time-slots-container">
|
<div class="time-slots-container">
|
||||||
<div class="time-labels">
|
<div class="time-labels">
|
||||||
<div v-for="hour in workHours" :key="hour" class="time-label">
|
<div v-for="hour in workHours" :key="hour" class="time-label">
|
||||||
@@ -164,6 +198,21 @@
|
|||||||
{{ currentDayData.dayNumber }}. {{ $t(`personal.calendar.months.${currentDayData.month}`) }} {{ currentDayData.year }}
|
{{ currentDayData.dayNumber }}. {{ $t(`personal.calendar.months.${currentDayData.month}`) }} {{ currentDayData.year }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- All-day events for this day -->
|
||||||
|
<div v-if="getEventsForDateAllDay(currentDateStr).length > 0" class="all-day-section">
|
||||||
|
<div class="all-day-label">{{ $t('personal.calendar.allDay') }}</div>
|
||||||
|
<div class="all-day-events-day">
|
||||||
|
<div
|
||||||
|
v-for="event in getEventsForDateAllDay(currentDateStr)"
|
||||||
|
:key="event.id"
|
||||||
|
class="all-day-event"
|
||||||
|
:style="{ backgroundColor: getCategoryColor(event.categoryId) }"
|
||||||
|
@click="editEvent(event)"
|
||||||
|
>
|
||||||
|
{{ event.title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="time-slots-container single-day">
|
<div class="time-slots-container single-day">
|
||||||
<div class="time-labels">
|
<div class="time-labels">
|
||||||
<div v-for="hour in hours" :key="hour" class="time-label">
|
<div v-for="hour in hours" :key="hour" class="time-label">
|
||||||
@@ -595,6 +644,17 @@ export default {
|
|||||||
return dateStr >= eventStart && dateStr <= eventEnd;
|
return dateStr >= eventStart && dateStr <= eventEnd;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
getEventsForDateAllDay(dateStr) {
|
||||||
|
return this.events.filter(event => {
|
||||||
|
if (!event.allDay) return false;
|
||||||
|
const eventStart = event.startDate;
|
||||||
|
const eventEnd = event.endDate || event.startDate;
|
||||||
|
return dateStr >= eventStart && dateStr <= eventEnd;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
hasAnyAllDayEvents(daysData) {
|
||||||
|
return daysData.some(day => this.getEventsForDateAllDay(day.date).length > 0);
|
||||||
|
},
|
||||||
getEventsForDateTime(dateStr, hour) {
|
getEventsForDateTime(dateStr, hour) {
|
||||||
return this.events.filter(event => {
|
return this.events.filter(event => {
|
||||||
if (event.allDay) return false;
|
if (event.allDay) return false;
|
||||||
@@ -1003,6 +1063,77 @@ h2 {
|
|||||||
background: #f8f8f8;
|
background: #f8f8f8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All-day events row (week/workweek views)
|
||||||
|
.all-day-row {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
background: #fafafa;
|
||||||
|
min-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-day-label {
|
||||||
|
width: 60px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 8px 4px;
|
||||||
|
font-size: 0.75em;
|
||||||
|
color: #888;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-day-events {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-day-cell {
|
||||||
|
flex: 1;
|
||||||
|
padding: 4px;
|
||||||
|
border-left: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-day-event {
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #fff;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All-day section (day view)
|
||||||
|
.all-day-section {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
background: #fafafa;
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-day-events-day {
|
||||||
|
flex: 1;
|
||||||
|
padding: 4px 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
.all-day-event {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.time-header-spacer {
|
.time-header-spacer {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user