/** * Modul: RRULE UI-Helfer * Zweck: Wiederholungs-Formular (HTML + Logik) für Aufgaben- und Kalender-Modals * Abhängigkeiten: keine */ const FREQ_OPTIONS = [ { value: '', label: 'Keine Wiederholung' }, { value: 'DAILY', label: 'Täglich' }, { value: 'WEEKLY', label: 'Wöchentlich' }, { value: 'MONTHLY', label: 'Monatlich' }, ]; const WEEKDAYS = [ { value: 'MO', label: 'Mo' }, { value: 'TU', label: 'Di' }, { value: 'WE', label: 'Mi' }, { value: 'TH', label: 'Do' }, { value: 'FR', label: 'Fr' }, { value: 'SA', label: 'Sa' }, { value: 'SU', label: 'So' }, ]; /** * Parsed einen RRULE-String in ein Objekt für die UI. * @param {string|null} rule - z.B. "FREQ=WEEKLY;BYDAY=MO,TH;INTERVAL=2" * @returns {{ freq: string, interval: number, byday: string[], until: string }} */ export function parseRRule(rule) { const result = { freq: '', interval: 1, byday: [], until: '' }; if (!rule) return result; for (const segment of rule.split(';')) { const eq = segment.indexOf('='); if (eq === -1) continue; const key = segment.slice(0, eq).toUpperCase(); const val = segment.slice(eq + 1); if (key === 'FREQ') result.freq = val; if (key === 'INTERVAL') result.interval = parseInt(val, 10) || 1; if (key === 'BYDAY') result.byday = val.split(',').map(d => d.trim()); if (key === 'UNTIL') { // YYYYMMDD → YYYY-MM-DD const c = val.replace(/[TZ]/g, ''); result.until = `${c.slice(0, 4)}-${c.slice(4, 6)}-${c.slice(6, 8)}`; } } return result; } /** * Baut einen RRULE-String aus den UI-Werten. * @param {{ freq: string, interval: number, byday: string[], until: string }} opts * @returns {string|null} - RRULE-String oder null (keine Wiederholung) */ export function buildRRule({ freq, interval, byday, until }) { if (!freq) return null; const parts = [`FREQ=${freq}`]; if (interval > 1) parts.push(`INTERVAL=${interval}`); if (freq === 'WEEKLY' && byday.length > 0) { parts.push(`BYDAY=${byday.join(',')}`); } if (until) { parts.push(`UNTIL=${until.replace(/-/g, '')}T235959Z`); } return parts.join(';'); } /** * Rendert das HTML für die Wiederholungs-Felder. * @param {string} prefix - ID-Prefix (z.B. "task" oder "event") * @param {string|null} existingRule - bestehende RRULE oder null * @returns {string} HTML-String */ export function renderRRuleFields(prefix, existingRule) { const parsed = parseRRule(existingRule); const freqOpts = FREQ_OPTIONS.map(o => `` ).join(''); const dayBtns = WEEKDAYS.map(d => `` ).join(''); return `