Fix Kalender-Suche: Sync-Fehler sichtbar, force-sync beim Kalender-Refresh, Backdrop opak
This commit is contained in:
@@ -71,12 +71,6 @@ router.post('/sync-calendar', authenticate, async (req, res) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ins = db.prepare(`
|
|
||||||
INSERT INTO calendar_event_cache
|
|
||||||
(feed_id, user_id, summary, description, location, start_dt, end_dt, synced_at)
|
|
||||||
VALUES (?,?,?,?,?,?,?,datetime('now','localtime'))
|
|
||||||
`);
|
|
||||||
|
|
||||||
let totalSynced = 0;
|
let totalSynced = 0;
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
|
||||||
@@ -85,16 +79,27 @@ router.post('/sync-calendar', authenticate, async (req, res) => {
|
|||||||
const raw = await fetchIcal(feed.url);
|
const raw = await fetchIcal(feed.url);
|
||||||
if (!raw) { errors.push(`${feed.name}: kein gültiger iCal-Feed`); continue; }
|
if (!raw) { errors.push(`${feed.name}: kein gültiger iCal-Feed`); continue; }
|
||||||
const events = parseIcal(raw);
|
const events = parseIcal(raw);
|
||||||
|
if (!events.length) { errors.push(`${feed.name}: 0 Events geparst`); continue; }
|
||||||
|
// prepare INSIDE try-catch – wirft wenn Tabelle nicht existiert
|
||||||
|
const ins = db.prepare(`
|
||||||
|
INSERT INTO calendar_event_cache
|
||||||
|
(feed_id, user_id, summary, description, location, start_dt, end_dt, synced_at)
|
||||||
|
VALUES (?,?,?,?,?,?,?,datetime('now','localtime'))
|
||||||
|
`);
|
||||||
db.transaction(() => {
|
db.transaction(() => {
|
||||||
db.prepare('DELETE FROM calendar_event_cache WHERE feed_id=?').run(feed.id);
|
db.prepare('DELETE FROM calendar_event_cache WHERE feed_id=?').run(feed.id);
|
||||||
events.slice(0, 300).forEach(ev =>
|
events.slice(0, 300).forEach(ev =>
|
||||||
ins.run(feed.id, uid, ev.summary, ev.description, ev.location, ev.start, ev.end)
|
ins.run(feed.id, uid, ev.summary||'', ev.description||'', ev.location||'', ev.start||'', ev.end||'')
|
||||||
);
|
);
|
||||||
})();
|
})();
|
||||||
totalSynced += events.length;
|
totalSynced += events.length;
|
||||||
} catch(e) { errors.push(`${feed.name}: ${e.message}`); }
|
} catch(e) {
|
||||||
|
console.error(`[CalendarSync] Feed "${feed.name}" (${feed.url}): ${e.message}`);
|
||||||
|
errors.push(`${feed.name}: ${e.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`[CalendarSync] uid=${uid} synced=${totalSynced} feeds=${feeds.length} errors=${errors.length}`);
|
||||||
res.json({ ok: true, synced: totalSynced, feeds: feeds.length, errors });
|
res.json({ ok: true, synced: totalSynced, feeds: feeds.length, errors });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1859,9 +1859,9 @@ function GlobalSearch({ setActive, setDevToolsNav, mobile }) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Backdrop zum Schließen */}
|
{/* Backdrop zum Schließen – leicht opak damit Dashboard nicht durchscheint */}
|
||||||
{showDropdown && (
|
{showDropdown && (
|
||||||
<div style={{position:'fixed',inset:0,zIndex:8999}} onClick={close}/>
|
<div style={{position:'fixed',inset:0,zIndex:8999,background:'rgba(0,0,0,0.25)'}} onClick={close}/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -1875,7 +1875,9 @@ function Dashboard({ toast, mobile, setActive, setDevToolsNav, unreadMsgs=0, unr
|
|||||||
useEffect(() => { const t = setInterval(() => setNow(new Date()), 30000); return () => clearInterval(t); }, []);
|
useEffect(() => { const t = setInterval(() => setNow(new Date()), 30000); return () => clearInterval(t); }, []);
|
||||||
// Kalender-Events im Hintergrund für die Suche cachen
|
// Kalender-Events im Hintergrund für die Suche cachen
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
api('/search/sync-calendar', { method:'POST', body:{} }).catch(()=>{});
|
api('/search/sync-calendar', { method:'POST', body:{} })
|
||||||
|
.then(r => { if (r.errors?.length) console.warn('[CalendarSync]', r); })
|
||||||
|
.catch(e => console.error('[CalendarSync] Fehler:', e));
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: mobile ? '14px 12px 90px' : '36px 44px', maxWidth:1100 }}>
|
<div style={{ padding: mobile ? '14px 12px 90px' : '36px 44px', maxWidth:1100 }}>
|
||||||
|
|||||||
@@ -121,7 +121,11 @@ export default function CalendarWidget() {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const refresh = () => { api('/calendar/feeds').then(f=>{ setFeeds(f); loadFeeds(f); }).catch(()=>{}); };
|
const refresh = () => {
|
||||||
|
api('/calendar/feeds').then(f=>{ setFeeds(f); loadFeeds(f); }).catch(()=>{});
|
||||||
|
// Kalender-Cache für Suche mitsynchronisieren
|
||||||
|
api('/search/sync-calendar', { method:'POST', body:{ force:true } }).catch(()=>{});
|
||||||
|
};
|
||||||
// Load on mount so next event shows without opening
|
// Load on mount so next event shows without opening
|
||||||
useEffect(() => { refresh(); }, []);
|
useEffect(() => { refresh(); }, []);
|
||||||
// Reload when opened
|
// Reload when opened
|
||||||
@@ -172,7 +176,7 @@ export default function CalendarWidget() {
|
|||||||
<span style={{ color:'rgba(255,255,255,0.35)', fontFamily:'monospace', fontSize:9, flexShrink:0 }}>
|
<span style={{ color:'rgba(255,255,255,0.35)', fontFamily:'monospace', fontSize:9, flexShrink:0 }}>
|
||||||
{nextEvent.allDay
|
{nextEvent.allDay
|
||||||
? nextEvent.dtstart.toLocaleDateString('de-DE',{day:'numeric',month:'short'})
|
? nextEvent.dtstart.toLocaleDateString('de-DE',{day:'numeric',month:'short'})
|
||||||
: `${nextEvent.dtstart.toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit'})} ${nextEvent.dtstart.toLocaleTimeString('de-DE',{hour:'2-digit',minute:'2-digit'})}`
|
: nextEvent.dtstart.toLocaleTimeString('de-DE',{hour:'2-digit',minute:'2-digit'})
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user