Aktueller Stand

This commit is contained in:
2026-01-17 17:19:11 +01:00
parent 056d798fbe
commit 07f41f3ed6

View File

@@ -527,6 +527,27 @@ export default function CalendarBoard() {
setFormOpen(true); setFormOpen(true);
}; };
const applyTruncatedTitles = (root: HTMLElement) => {
const elements = Array.from(
root.querySelectorAll<HTMLElement>(".event-shell .truncate")
);
elements.forEach((element) => {
const text = element.textContent?.trim();
if (!text) {
element.removeAttribute("title");
return;
}
const isTruncated =
element.scrollWidth > element.clientWidth ||
element.scrollHeight > element.clientHeight;
if (isTruncated) {
element.setAttribute("title", text);
} else {
element.removeAttribute("title");
}
});
};
const calendarEvents = useMemo( const calendarEvents = useMemo(
() => () =>
events.map((event) => ({ events.map((event) => ({
@@ -1061,6 +1082,10 @@ export default function CalendarBoard() {
</div> </div>
); );
}} }}
eventDidMount={(info) => {
if (!info.el) return;
requestAnimationFrame(() => applyTruncatedTitles(info.el));
}}
height="auto" height="auto"
datesSet={(arg) => { datesSet={(arg) => {
setActiveRange({ setActiveRange({
@@ -1467,57 +1492,77 @@ export default function CalendarBoard() {
</td> </td>
</tr> </tr>
) : ( ) : (
displayedEvents.map((event) => ( displayedEvents.map((event) => {
<tr const categoryName = event.category?.name || "Ohne Kategorie";
key={event.id} const locationLabel = formatLocation(event.location);
data-bucket={getDateBucket(event.startAt)} return (
className={`border-t border-slate-200 ${ <tr
getDateBucket(event.startAt) === "past" key={event.id}
? "bg-slate-50 text-slate-500" data-bucket={getDateBucket(event.startAt)}
: getDateBucket(event.startAt) === "today" className={`border-t border-slate-200 ${
? "bg-amber-50/60" getDateBucket(event.startAt) === "past"
: getDateBucket(event.startAt) === "tomorrow" ? "bg-slate-50 text-slate-500"
? "bg-emerald-50/60" : getDateBucket(event.startAt) === "today"
: "bg-sky-50/40" ? "bg-amber-50/60"
}`} : getDateBucket(event.startAt) === "tomorrow"
> ? "bg-emerald-50/60"
{isAdmin && ( : "bg-sky-50/40"
<td className="py-3 pr-3 pl-2"> }`}
<input >
type="checkbox" {isAdmin && (
aria-label={`${event.title} auswählen`} <td className="py-3 pr-3 pl-2">
checked={bulkSelection.has(event.id)} <input
onChange={() => toggleBulkSelection(event.id)} type="checkbox"
/> aria-label={`${event.title} auswählen`}
checked={bulkSelection.has(event.id)}
onChange={() => toggleBulkSelection(event.id)}
/>
</td>
)}
<td className="py-3 pr-3 pl-2 whitespace-nowrap">
{new Date(event.startAt).toLocaleString("de-DE", {
dateStyle: "medium",
timeStyle: "short"
})}
</td> </td>
)} <td className="py-3 pr-3 font-medium">
<td className="py-3 pr-3 pl-2 whitespace-nowrap"> <span
{new Date(event.startAt).toLocaleString("de-DE", { className="block max-w-[200px] truncate sm:max-w-[280px] lg:max-w-[420px] xl:max-w-[520px] 2xl:max-w-[640px]"
dateStyle: "medium", title={event.title}
timeStyle: "short" >
})} {event.title}
</td> </span>
<td className="py-3 pr-3 font-medium">{event.title}</td> </td>
<td className="py-3 pr-3"> <td className="py-3 pr-3">
{event.category?.name || "Ohne Kategorie"} <span
</td> className="block max-w-[160px] truncate sm:max-w-[220px] lg:max-w-[280px] xl:max-w-[320px]"
<td className="py-3 pr-3"> title={categoryName}
<div className="flex items-center justify-between gap-2"> >
<span className="flex-1">{formatLocation(event.location)}</span> {categoryName}
{event.locationLat && event.locationLng && ( </span>
<a </td>
className="inline-flex items-center justify-center rounded-full border border-slate-200 p-1 text-slate-600 hover:bg-slate-100" <td className="py-3 pr-3">
href={`https://maps.google.com/?q=${event.locationLat},${event.locationLng}&z=14`} <div className="flex items-center justify-between gap-2">
target="_blank" <span
rel="noreferrer" className="min-w-0 flex-1 truncate"
title="Google Maps" title={locationLabel}
aria-label="Google Maps"
> >
<IconMapPin /> {locationLabel}
</a> </span>
)} {event.locationLat && event.locationLng && (
</div> <a
</td> className="inline-flex items-center justify-center rounded-full border border-slate-200 p-1 text-slate-600 hover:bg-slate-100"
href={`https://maps.google.com/?q=${event.locationLat},${event.locationLng}&z=14`}
target="_blank"
rel="noreferrer"
title="Google Maps"
aria-label="Google Maps"
>
<IconMapPin />
</a>
)}
</div>
</td>
<td className="py-3 pr-3"> <td className="py-3 pr-3">
<div className="flex flex-nowrap gap-1"> <div className="flex flex-nowrap gap-1">
{canManageView && ( {canManageView && (
@@ -1577,8 +1622,9 @@ export default function CalendarBoard() {
</button> </button>
</div> </div>
</td> </td>
</tr> </tr>
)) );
})
)} )}
</tbody> </tbody>
</table> </table>