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
This commit is contained in:
@@ -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}
|
||||
/>
|
||||
</div>
|
||||
@@ -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}
|
||||
/>
|
||||
</div>
|
||||
@@ -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}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -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<Event>;
|
||||
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);
|
||||
|
||||
@@ -33,7 +33,7 @@ const Ressourcen: React.FC = () => {
|
||||
const [groupOrder, setGroupOrder] = useState<number[]>([]);
|
||||
const [showOrderPanel, setShowOrderPanel] = useState<boolean>(false);
|
||||
const [timelineView] = useState<TimelineView>('day');
|
||||
const [viewDate] = useState<Date>(() => {
|
||||
const [viewDate, setViewDate] = useState<Date>(() => {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ViewsDirective>
|
||||
<ViewDirective option="TimelineDay" displayName="Tag"></ViewDirective>
|
||||
|
||||
Reference in New Issue
Block a user