feat: Kalender-Termine zeigen Icons + Start-Ende-Uhrzeit
* 📅-Icon bei ganztaegigen Terminen * 🔁-Icon bei wiederkehrenden Terminen * Anzeige "09:00-10:30" statt nur "09:00" in Woche/Tag-Ansicht * Mouseover-Tooltip mit allen Termin-Infos inklusive Ort und Beschreibung Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c5284f57e0
commit
ddd8f57e69
|
|
@ -21,7 +21,16 @@
|
|||
</aside>
|
||||
|
||||
<div class="calendar-main">
|
||||
<FullCalendar ref="fcRef" :options="calendarOptions" />
|
||||
<FullCalendar ref="fcRef" :options="calendarOptions">
|
||||
<template #eventContent="arg">
|
||||
<div class="fc-event-content-inner" :title="eventTooltip(arg.event)">
|
||||
<span v-if="arg.event.extendedProps.all_day" class="fc-icon">📅</span>
|
||||
<span v-else-if="arg.timeText" class="fc-time">{{ formatEventTime(arg.event) }}</span>
|
||||
<span v-if="arg.event.extendedProps.recurrence_rule" class="fc-icon" title="Wiederholung">🔁</span>
|
||||
<span class="fc-title">{{ arg.event.title }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</FullCalendar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -293,8 +302,31 @@ const calendarOptions = computed(() => ({
|
|||
select: onDateSelect,
|
||||
eventDrop: onEventDrop,
|
||||
eventResize: onEventDrop,
|
||||
displayEventEnd: true,
|
||||
eventTimeFormat: { hour: '2-digit', minute: '2-digit', hour12: false },
|
||||
}))
|
||||
|
||||
function formatEventTime(ev) {
|
||||
if (!ev.start) return ''
|
||||
const fmt = d => d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' })
|
||||
if (!ev.end) return fmt(ev.start)
|
||||
return `${fmt(ev.start)}–${fmt(ev.end)}`
|
||||
}
|
||||
|
||||
function eventTooltip(ev) {
|
||||
const p = ev.extendedProps
|
||||
const parts = [ev.title]
|
||||
if (p.all_day) parts.push('Ganztaegig')
|
||||
else if (ev.start) {
|
||||
const fmt = d => d.toLocaleString('de-DE', { hour: '2-digit', minute: '2-digit' })
|
||||
parts.push(ev.end ? `${fmt(ev.start)}–${fmt(ev.end)}` : fmt(ev.start))
|
||||
}
|
||||
if (p.recurrence_rule) parts.push('Wiederholung')
|
||||
if (p.location) parts.push('Ort: ' + p.location)
|
||||
if (p.description) parts.push(p.description)
|
||||
return parts.join(' • ')
|
||||
}
|
||||
|
||||
async function fetchEvents(info, successCallback, failureCallback) {
|
||||
try {
|
||||
const all = []
|
||||
|
|
@ -656,4 +688,8 @@ onMounted(async () => {
|
|||
.ical-url { font-size: 0.8rem; display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
|
||||
.ical-url code { background: var(--p-surface-100); padding: 0.25rem 0.5rem; border-radius: 4px; word-break: break-all; }
|
||||
.hint-badge { font-size: 0.75rem; color: var(--p-primary-700); display: inline-flex; gap: 0.25rem; align-items: center; }
|
||||
.fc-event-content-inner { display: flex; align-items: center; gap: 0.2rem; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; padding: 0 2px; }
|
||||
.fc-event-content-inner .fc-icon { flex-shrink: 0; font-size: 0.85em; }
|
||||
.fc-event-content-inner .fc-time { flex-shrink: 0; font-weight: 600; font-size: 0.8em; opacity: 0.9; }
|
||||
.fc-event-content-inner .fc-title { overflow: hidden; text-overflow: ellipsis; }
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue