From 90ccbdf920fecbc0c269510a7a4608f5f8f7af49 Mon Sep 17 00:00:00 2001 From: Olaf Date: Mon, 30 Mar 2026 09:51:22 +0000 Subject: [PATCH] fix(dashboard): restore event visibility and fix lint errors in App.tsx Appointments: no longer hide existing events on holiday dates Resources: load all overlapping events per group, include inactive/past events, and reload on date/view navigation App.tsx: replace any types in password input handlers with typed event shapes --- dashboard/src/App.tsx | 6 ++-- dashboard/src/appointments.tsx | 57 +++------------------------------- dashboard/src/ressourcen.tsx | 35 +++++++++++++++------ 3 files changed, 33 insertions(+), 65 deletions(-) diff --git a/dashboard/src/App.tsx b/dashboard/src/App.tsx index 05b5ffe..3cdb422 100644 --- a/dashboard/src/App.tsx +++ b/dashboard/src/App.tsx @@ -439,7 +439,7 @@ const Layout: React.FC = () => { type="password" placeholder="Aktuelles Passwort" value={pwdCurrent} - input={(e: any) => setPwdCurrent(e.value)} + input={(e: { value?: string }) => setPwdCurrent(e.value ?? '')} disabled={pwdBusy} /> @@ -449,7 +449,7 @@ const Layout: React.FC = () => { type="password" placeholder="Mindestens 6 Zeichen" value={pwdNew} - input={(e: any) => setPwdNew(e.value)} + input={(e: { value?: string }) => setPwdNew(e.value ?? '')} disabled={pwdBusy} /> @@ -459,7 +459,7 @@ const Layout: React.FC = () => { type="password" placeholder="Wiederholen" value={pwdConfirm} - input={(e: any) => setPwdConfirm(e.value)} + input={(e: { value?: string }) => setPwdConfirm(e.value ?? '')} disabled={pwdBusy} /> diff --git a/dashboard/src/appointments.tsx b/dashboard/src/appointments.tsx index 1a381bf..9fc5a66 100644 --- a/dashboard/src/appointments.tsx +++ b/dashboard/src/appointments.tsx @@ -523,28 +523,10 @@ const Appointments: React.FC = () => { }, [holidays, allowScheduleOnHolidays]); const dataSource = useMemo(() => { - // Filter: Events with SkipHolidays=true (from internal Event type) are never shown on holidays - const filteredEvents = events.filter(ev => { - if (ev.SkipHolidays) { - // If event falls within a holiday, hide it - const s = ev.StartTime instanceof Date ? ev.StartTime : new Date(ev.StartTime); - const e = ev.EndTime instanceof Date ? ev.EndTime : new Date(ev.EndTime); - for (const h of holidays) { - const hs = new Date(h.start_date + 'T00:00:00'); - const he = new Date(h.end_date + 'T23:59:59'); - if ( - (s >= hs && s <= he) || - (e >= hs && e <= he) || - (s <= hs && e >= he) - ) { - return false; - } - } - } - return true; - }); - return [...filteredEvents, ...holidayDisplayEvents, ...holidayBlockEvents]; - }, [events, holidayDisplayEvents, holidayBlockEvents, holidays]); + // Existing events should always be visible; holiday skipping for recurring events + // is handled via RecurrenceException from the backend. + return [...events, ...holidayDisplayEvents, ...holidayBlockEvents]; + }, [events, holidayDisplayEvents, holidayBlockEvents]); // Removed dataSource logging @@ -1227,37 +1209,6 @@ const Appointments: React.FC = () => { } }} eventRendered={(args: EventRenderedArgs) => { - // Always hide events that skip holidays when they fall on holidays, regardless of toggle - if (args.data) { - const ev = args.data as unknown as Partial; - if (ev.SkipHolidays && !args.data.isHoliday) { - const s = - args.data.StartTime instanceof Date - ? args.data.StartTime - : new Date(args.data.StartTime); - const e = - args.data.EndTime instanceof Date ? args.data.EndTime : new Date(args.data.EndTime); - if (isWithinHolidayRange(s, e)) { - args.cancel = true; - return; - } - } - } - - // Blende Nicht-Ferien-Events aus, falls sie in Ferien fallen und Terminieren nicht erlaubt ist - // Hide events on holidays if not allowed - if (!allowScheduleOnHolidays && args.data && !args.data.isHoliday) { - const s = - args.data.StartTime instanceof Date - ? args.data.StartTime - : new Date(args.data.StartTime); - const e = - args.data.EndTime instanceof Date ? args.data.EndTime : new Date(args.data.EndTime); - if (isWithinHolidayRange(s, e)) { - args.cancel = true; - return; - } - } if (selectedGroupId && args.data && args.data.Id) { const groupColor = getGroupColor(selectedGroupId, groups); diff --git a/dashboard/src/ressourcen.tsx b/dashboard/src/ressourcen.tsx index 05490ee..a57d5e5 100644 --- a/dashboard/src/ressourcen.tsx +++ b/dashboard/src/ressourcen.tsx @@ -33,7 +33,7 @@ const Ressourcen: React.FC = () => { const [groupOrder, setGroupOrder] = useState([]); const [showOrderPanel, setShowOrderPanel] = useState(false); const [timelineView] = useState('day'); - const [viewDate] = useState(() => { + const [viewDate, setViewDate] = useState(() => { const now = new Date(); now.setHours(0, 0, 0, 0); return now; @@ -110,23 +110,31 @@ const Ressourcen: React.FC = () => { for (const group of groups) { try { console.log(`[Ressourcen] Fetching events for group "${group.name}" (ID: ${group.id})`); - const apiEvents = await fetchEvents(group.id.toString(), false, { + const apiEvents = await fetchEvents(group.id.toString(), true, { start, end, }); console.log(`[Ressourcen] Got ${apiEvents?.length || 0} events for group "${group.name}"`); if (Array.isArray(apiEvents) && apiEvents.length > 0) { - const event = apiEvents[0]; - const eventTitle = event.subject || event.title || 'Unnamed Event'; - const eventType = event.type || event.event_type || 'other'; - const eventStart = event.startTime || event.start; - const eventEnd = event.endTime || event.end; + for (const event of apiEvents) { + const eventTitle = event.subject || event.title || 'Unnamed Event'; + const eventType = event.type || event.event_type || 'other'; + const eventStart = event.startTime || event.start; + const eventEnd = event.endTime || event.end; + + if (!eventStart || !eventEnd) { + continue; + } - if (eventStart && eventEnd) { const parsedStart = parseUTCDate(eventStart); const parsedEnd = parseUTCDate(eventEnd); + // Keep only events that overlap the visible range. + if (parsedEnd < start || parsedStart > end) { + continue; + } + // Capitalize first letter of event type const formattedType = eventType.charAt(0).toUpperCase() + eventType.slice(1); @@ -138,7 +146,6 @@ const Ressourcen: React.FC = () => { ResourceId: group.id, EventType: eventType, }); - console.log(`[Ressourcen] Group "${group.name}" has event: ${eventTitle}`); } } } catch (error) { @@ -324,6 +331,16 @@ const Ressourcen: React.FC = () => { group={{ resources: ['Groups'], allowGroupEdit: false }} timeScale={{ interval: 60, slotCount: 1 }} rowAutoHeight={false} + actionComplete={(args) => { + if (args.requestType === 'dateNavigate' || args.requestType === 'viewNavigate') { + const selected = scheduleRef.current?.selectedDate; + if (selected) { + const normalized = new Date(selected); + normalized.setHours(0, 0, 0, 0); + setViewDate(normalized); + } + } + }} >