feat: add edit button for ICS subscriptions (#100)
Adds a pencil-icon edit button to each ICS subscription row. Clicking it opens a modal to update name, color, and shared visibility via PATCH /calendar/subscriptions/:id. Adds updatedToast i18n key to all 15 locales. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1644,6 +1644,19 @@ function renderIcsList(container, subs, user) {
|
||||
syncBtn.appendChild(syncIcon);
|
||||
actions.appendChild(syncBtn);
|
||||
|
||||
const editBtn = document.createElement('button');
|
||||
editBtn.className = 'btn btn--icon btn--ghost';
|
||||
editBtn.title = t('settings.ics.actions.edit');
|
||||
editBtn.setAttribute('aria-label', t('settings.ics.actions.edit'));
|
||||
editBtn.dataset.action = 'ics-edit';
|
||||
editBtn.dataset.id = sub.id;
|
||||
const editIcon = document.createElement('i');
|
||||
editIcon.setAttribute('data-lucide', 'pencil');
|
||||
editIcon.style.cssText = 'width:14px;height:14px';
|
||||
editIcon.setAttribute('aria-hidden', 'true');
|
||||
editBtn.appendChild(editIcon);
|
||||
actions.appendChild(editBtn);
|
||||
|
||||
const delBtn = document.createElement('button');
|
||||
delBtn.className = 'btn btn--icon btn--danger-outline';
|
||||
delBtn.title = t('settings.ics.actions.delete');
|
||||
@@ -1756,6 +1769,52 @@ function bindIcsEvents(container, user, initialSubs) {
|
||||
}
|
||||
}
|
||||
|
||||
if (action === 'ics-edit') {
|
||||
const sub = subs.find((s) => s.id === id);
|
||||
if (!sub) return;
|
||||
openModal({
|
||||
title: t('settings.ics.actions.edit'),
|
||||
size: 'sm',
|
||||
content: `
|
||||
<form id="ics-edit-form" class="settings-form">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="ics-edit-name">${t('settings.ics.form.name')}</label>
|
||||
<input class="form-input" type="text" id="ics-edit-name" value="${esc(sub.name)}" required maxlength="100" />
|
||||
</div>
|
||||
<div class="settings-name-color-row">
|
||||
<div class="form-group settings-color-field">
|
||||
<label class="form-label" for="ics-edit-color">${t('settings.ics.form.color')}</label>
|
||||
<input class="settings-color-button" type="color" id="ics-edit-color" value="${esc(sub.color || '#3b82f6')}" />
|
||||
</div>
|
||||
<div class="form-group" style="display:flex;align-items:center;gap:var(--space-2);padding-top:var(--space-5)">
|
||||
<input type="checkbox" id="ics-edit-shared" ${sub.shared ? 'checked' : ''} />
|
||||
<label class="form-label" for="ics-edit-shared" style="margin:0">${t('settings.ics.form.shared')}</label>
|
||||
</div>
|
||||
</div>
|
||||
<p id="ics-edit-error" class="form-error" hidden></p>
|
||||
</form>
|
||||
`,
|
||||
onSave: async (modalEl, close) => {
|
||||
const name = modalEl.querySelector('#ics-edit-name').value.trim();
|
||||
const color = modalEl.querySelector('#ics-edit-color').value;
|
||||
const shared = modalEl.querySelector('#ics-edit-shared').checked ? 1 : 0;
|
||||
const errEl = modalEl.querySelector('#ics-edit-error');
|
||||
errEl.hidden = true;
|
||||
try {
|
||||
const res = await api.patch(`/calendar/subscriptions/${id}`, { name, color, shared });
|
||||
const idx = subs.findIndex((s) => s.id === id);
|
||||
if (idx >= 0) subs[idx] = res.data;
|
||||
renderIcsList(container, subs, user);
|
||||
window.oikos?.showToast(t('settings.ics.updatedToast'), 'success');
|
||||
close();
|
||||
} catch (err) {
|
||||
errEl.textContent = err.message ?? t('common.errorGeneric');
|
||||
errEl.hidden = false;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (action === 'ics-delete') {
|
||||
const name = target.dataset.name;
|
||||
if (!await confirmModal(t('settings.ics.confirm_delete'), { danger: true, confirmLabel: t('common.delete') })) return;
|
||||
|
||||
Reference in New Issue
Block a user