diff --git a/config.php b/config.php index 20f7176..8b2564b 100644 --- a/config.php +++ b/config.php @@ -1,7 +1,7 @@ 'geburtstag', 'appointment' => 'termin']; + $tags = array_map(fn($t) => $aliases[$t] ?? $t, array_map('strtolower', $matches[1] ?? [])); + return implode(',', array_unique($tags)); } // Plugin route handlers (registered by plugin backend.php files). diff --git a/public/js/modules/editor.js b/public/js/modules/editor.js index bd7ebb4..9750cad 100644 --- a/public/js/modules/editor.js +++ b/public/js/modules/editor.js @@ -234,7 +234,7 @@ export function openModal(card = null) { // `card` can be `null` (add-button new) or a shell `{id: null, ...}` // from the calendar day-popup — both count as "new", so key on // card?.id not the card ref itself. - const isNewAppointment = !card?.id && /#(termin|geburtstag)\b/.test(body.value); + const isNewAppointment = !card?.id && /#(termin|appointment|geburtstag|birthday)\b/.test(body.value); inpBucket.value = card?.bucket_id ? card.bucket_id : (isNewAppointment ? '' : (!virtualBuckets.includes(state.activeBucket) ? state.activeBucket : '')); @@ -512,7 +512,7 @@ async function doSave(close, { animate = true } = {}) { } await window._reloadAll(); // Auto-sync if card has #termin or #geburtstag - if (data.body && /#(termin|geburtstag)\b/.test(data.body)) { + if (data.body && /#(termin|appointment|geburtstag|birthday)\b/.test(data.body)) { window._triggerSync?.(); } if (close) { diff --git a/public/plugins/tests/undo.test.js b/public/plugins/tests/undo.test.js index a3aeab6..aecca9c 100644 --- a/public/plugins/tests/undo.test.js +++ b/public/plugins/tests/undo.test.js @@ -109,11 +109,17 @@ describe('Undo: Editor Save', () => { bodyEl.dispatchEvent(new Event('input', { bubbles: true })); click('#modal-save-close'); + // Wait for both the server patch AND the modal close before firing + // Ctrl+Z — the global undo shortcut is guarded by + // `!guards.isOpen('modal')`, so if doSave's closeModal() hasn't run + // yet (it only fires after the post-save _reloadAll), the undo key + // is swallowed silently and the test races the client's save flow. let card; for (let i = 0; i < 40; i++) { await sleep(100); card = (await fetch(`api/cards?ids=${res.id}`).then(r => r.json())).find(c => c.id == res.id); - if ((card?.body || '').includes('after edit')) break; + const modalClosed = !document.getElementById('modal')?.classList.contains('open'); + if ((card?.body || '').includes('after edit') && modalClosed) break; } expect(card.body).toContain('after edit'); diff --git a/website/index.html b/website/index.html index c764499..f871e50 100644 --- a/website/index.html +++ b/website/index.html @@ -352,10 +352,10 @@ footer { #ops #done #meeting - #termin + #appointment #research #idea - #geburtstag + #birthday #personal @@ -407,8 +407,8 @@ See also: [[Infra checklist]]
A month-grid calendar built into hyprcrd. Journal entries, appointments, and birthdays — all just cards with the right title or tag. Bidirectional CalDAV sync with ownCloud and Nextcloud.
YYYY-MM-DD, one per day, no tag needed#termin tag + structured template (time, end, location, attendees)#geburtstag tag, recurring annually#appointment tag + structured template (time, end, location, attendees)#birthday tag, recurring annually