feat: 'Vor dem Kopieren bearbeiten' Checkbox im Kopieren-Popup
Über der Kalenderliste im Kopieren-Menü gibt es jetzt eine Checkbox 'Vor dem Kopieren bearbeiten'. Wenn aktiviert und ein Ziel-Kalender geklickt wird, öffnet sich der Termin-erstellen-Dialog mit allen Daten des Quell-Termins vorausgefüllt (Titel, Datum, Ort, Beschreibung, Farbe, Wiederholung) und dem Ziel-Kalender vorausgewählt.
This commit is contained in:
@@ -846,6 +846,15 @@ a { color: var(--primary); text-decoration: none; }
|
||||
}
|
||||
.popup-copy-item:hover { background: var(--bg-hover); }
|
||||
.popup-copy-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
|
||||
.popup-copy-edit-toggle {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
padding: 6px 14px 8px;
|
||||
font-size: 12px; color: var(--text-2);
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid var(--border);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.popup-copy-edit-toggle input[type="checkbox"] { margin: 0; cursor: pointer; }
|
||||
|
||||
/* ── Settings Page ──────────────────────────────────────── */
|
||||
#modal-settings.modal-overlay {
|
||||
|
||||
@@ -1027,7 +1027,12 @@ function showEventPopup(ev, anchor) {
|
||||
if (!menu.classList.contains('hidden')) { menu.classList.add('hidden'); return; }
|
||||
const targets = buildWritableCalendars(ev);
|
||||
if (!targets.length) { showToast('Keine Zielkalender verfügbar', true); return; }
|
||||
menu.innerHTML = `<div class="popup-copy-label">${t('copy_to_calendar')}</div>` +
|
||||
menu.innerHTML =
|
||||
`<div class="popup-copy-label">${t('copy_to_calendar')}</div>` +
|
||||
`<label class="popup-copy-edit-toggle">
|
||||
<input type="checkbox" id="popup-copy-edit-cb" />
|
||||
<span>${t('edit_before_copy')}</span>
|
||||
</label>` +
|
||||
targets.map(c =>
|
||||
`<div class="popup-copy-item" data-cal-idx="${c._idx}">
|
||||
<span class="popup-copy-dot" style="background:${c.color}"></span>
|
||||
@@ -1035,13 +1040,22 @@ function showEventPopup(ev, anchor) {
|
||||
</div>`
|
||||
).join('');
|
||||
menu.classList.remove('hidden');
|
||||
|
||||
// Stop clicks on the checkbox label from closing the menu
|
||||
menu.querySelector('.popup-copy-edit-toggle').addEventListener('click', e2 => e2.stopPropagation());
|
||||
|
||||
menu.querySelectorAll('.popup-copy-item').forEach(el => {
|
||||
el.addEventListener('click', async ev2 => {
|
||||
ev2.stopPropagation();
|
||||
const editFirst = document.getElementById('popup-copy-edit-cb').checked;
|
||||
menu.classList.add('hidden');
|
||||
popup.classList.add('hidden');
|
||||
const cal = targets[parseInt(el.dataset.calIdx)];
|
||||
await copyEventToCalendar(ev, cal);
|
||||
if (editFirst) {
|
||||
openCopyEditModal(ev, cal);
|
||||
} else {
|
||||
await copyEventToCalendar(ev, cal);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1149,6 +1163,43 @@ function openNewEventModal(date) {
|
||||
openModal('modal-event');
|
||||
}
|
||||
|
||||
// Open the create-event modal pre-filled with an existing event's data, so
|
||||
// the user can edit before copying it into the target calendar.
|
||||
function openCopyEditModal(ev, targetCal) {
|
||||
state.editingEvent = null;
|
||||
state.selectedEventColor = ev.color || '';
|
||||
|
||||
document.getElementById('modal-event-title-label').textContent = 'Termin erstellen';
|
||||
document.getElementById('ev-title').value = ev.title || '';
|
||||
document.getElementById('ev-location').value = ev.location || '';
|
||||
document.getElementById('ev-description').value = ev.description || '';
|
||||
document.getElementById('ev-allday').checked = !!ev.allDay;
|
||||
|
||||
if (ev.allDay) {
|
||||
setDtValue('ev-start-date', (ev.start || '').slice(0, 10), 'date');
|
||||
setDtValue('ev-end-date', (ev.end || '').slice(0, 10), 'date');
|
||||
} else {
|
||||
const s = new Date(ev.start);
|
||||
const e = new Date(ev.end);
|
||||
setDtValue('ev-start', toLocalDatetimeInput(s), 'datetime');
|
||||
setDtValue('ev-end', toLocalDatetimeInput(e), 'datetime');
|
||||
}
|
||||
|
||||
toggleAlldayFields(!!ev.allDay);
|
||||
|
||||
// Map target calendar to the dropdown's option value
|
||||
let selectedId;
|
||||
if (targetCal.type === 'caldav') selectedId = targetCal.id;
|
||||
else selectedId = `${targetCal.type}-${targetCal.id}`;
|
||||
populateCalendarSelect(selectedId);
|
||||
|
||||
resetColorPicker(ev.color || '');
|
||||
resetRecurrenceUI();
|
||||
if (ev.rrule) parseRruleIntoUI(ev.rrule);
|
||||
document.getElementById('ev-delete').classList.add('hidden');
|
||||
openModal('modal-event');
|
||||
}
|
||||
|
||||
function openEditEventModal(ev) {
|
||||
if (ev.source === 'ical') { showToast(t('event_readonly'), true); return; }
|
||||
state.editingEvent = ev;
|
||||
|
||||
@@ -153,6 +153,7 @@ const translations = {
|
||||
rec_ends: 'Endet', rec_never: 'Nie', rec_after_count: 'Nach Anzahl',
|
||||
rec_on_date: 'Am Datum', rec_occurrences: 'Termine',
|
||||
copy_to_calendar: 'Kopieren nach…', event_copied: 'Termin kopiert',
|
||||
edit_before_copy: 'Vor dem Kopieren bearbeiten',
|
||||
event_updated: 'Termin aktualisiert', event_created: 'Termin erstellt',
|
||||
confirm_delete_event: '"{title}" wirklich löschen?',
|
||||
confirm_delete_title: 'Termin löschen',
|
||||
@@ -361,6 +362,7 @@ const translations = {
|
||||
rec_ends: 'Ends', rec_never: 'Never', rec_after_count: 'After count',
|
||||
rec_on_date: 'On date', rec_occurrences: 'occurrences',
|
||||
copy_to_calendar: 'Copy to…', event_copied: 'Event copied',
|
||||
edit_before_copy: 'Edit before copying',
|
||||
event_updated: 'Event updated', event_created: 'Event created',
|
||||
confirm_delete_event: 'Really delete "{title}"?',
|
||||
confirm_delete_title: 'Delete event',
|
||||
|
||||
Reference in New Issue
Block a user