v0.0.5: gedeelde mailboxen (info@, facturen@, nieuwsbrief@, persoonlijk) met eigen IMAP/SMTP, afzender, rol en toegang per gebruiker; inbox per mailbox en versturen vanuit een gekozen mailbox; routines (jobs.py: types met @jobs.register, interval, instellingen, logboek, slot tegen dubbel draaien; app.py scheduler/tick) voor e-mail ophalen, nieuwsbrieven versturen en opschonen; meldingen (bel, bureaubladmelding); nieuwsbrieven met segmenten, testmail, inplannen en versturen per batch over één verbinding, afmeldlink met List-Unsubscribe en bounceverwerking; oude mailinstellingen worden de eerste mailbox
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8f6e1ab443
commit
cad838f1f4
@@ -0,0 +1,32 @@
|
||||
// Bel in de bovenbalk: elke minuut het aantal ongelezen meldingen ophalen (/notifications/poll). Met toestemming
|
||||
// van de browser verschijnen nieuwe meldingen ook als bureaubladmelding (zolang de CRM ergens open staat).
|
||||
(() => {
|
||||
const bell = document.querySelector('.bell[data-poll]');
|
||||
if (!bell) return;
|
||||
const count = bell.querySelector('.bell-count');
|
||||
const desktop = bell.querySelector('.bell-desktop');
|
||||
let last = Number(bell.dataset.last) || 0;
|
||||
const canNotify = 'Notification' in window;
|
||||
if (canNotify && Notification.permission === 'default') {
|
||||
desktop.hidden = false;
|
||||
desktop.addEventListener('click', () => Notification.requestPermission().then(() => { desktop.hidden = true; }));
|
||||
}
|
||||
async function poll() {
|
||||
try {
|
||||
const r = await fetch(`${bell.dataset.poll}?after=${last}`, { headers: { Accept: 'application/json' } });
|
||||
if (!r.ok) return;
|
||||
const d = await r.json();
|
||||
count.textContent = d.count;
|
||||
count.hidden = !d.count;
|
||||
d.items.slice().reverse().forEach((n) => {
|
||||
last = Math.max(last, n.id);
|
||||
if (canNotify && Notification.permission === 'granted') {
|
||||
const note = new Notification(n.title, { body: n.body || '', tag: `crm-${n.id}` });
|
||||
note.onclick = () => { window.focus(); location = n.url; };
|
||||
}
|
||||
});
|
||||
} catch (e) { /* offline of uitgelogd: volgende keer opnieuw */ }
|
||||
}
|
||||
setInterval(() => { if (!document.hidden) poll(); }, 60000);
|
||||
document.addEventListener('visibilitychange', () => { if (!document.hidden) poll(); });
|
||||
})();
|
||||
Reference in New Issue
Block a user