Add drag-resizable columns to the calendar settings table
Column widths are draggable via a handle on each header's right edge and persisted in localStorage (re-applied on re-render). Uses fixed table layout locked to measured px widths so resizing one column doesn't reflow the others. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1479,6 +1479,13 @@ a { color: var(--primary); text-decoration: none; }
|
|||||||
}
|
}
|
||||||
.cal-manage-table td { padding: 6px 8px 6px 0; border-bottom: 1px solid var(--border-light); vertical-align: middle; }
|
.cal-manage-table td { padding: 6px 8px 6px 0; border-bottom: 1px solid var(--border-light); vertical-align: middle; }
|
||||||
.cal-manage-table tbody tr:last-child td { border-bottom: none; }
|
.cal-manage-table tbody tr:last-child td { border-bottom: none; }
|
||||||
|
/* Drag-resizable columns: a grab handle on each header's right edge. */
|
||||||
|
.cal-manage-table th { position: relative; }
|
||||||
|
.cal-manage-table th .col-resizer {
|
||||||
|
position: absolute; top: 0; right: 0; width: 8px; height: 100%;
|
||||||
|
cursor: col-resize; user-select: none; touch-action: none;
|
||||||
|
}
|
||||||
|
.cal-manage-table th .col-resizer:hover { background: var(--border); }
|
||||||
.ct-acc-row td { padding-top: 14px; background: none; }
|
.ct-acc-row td { padding-top: 14px; background: none; }
|
||||||
.ct-acc-row td:first-child { font-size: 13px; }
|
.ct-acc-row td:first-child { font-size: 13px; }
|
||||||
.ct-cal-row .ct-indent { padding-left: 16px; }
|
.ct-cal-row .ct-indent { padding-left: 16px; }
|
||||||
|
|||||||
@@ -3717,6 +3717,55 @@ function renderHiddenCalendars() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Make the calendar-management table's columns drag-resizable. Widths persist
|
||||||
|
* in localStorage and are re-applied on every re-render. */
|
||||||
|
function initResizableCalTable(table) {
|
||||||
|
if (!table || !table.tHead) return;
|
||||||
|
const ths = Array.from(table.tHead.rows[0].cells);
|
||||||
|
let saved = null;
|
||||||
|
try { saved = JSON.parse(localStorage.getItem('calTableColWidths') || 'null'); } catch { saved = null; }
|
||||||
|
// Measure natural widths, then lock to px + fixed layout so dragging one
|
||||||
|
// column doesn't reflow the others.
|
||||||
|
const natural = ths.map(th => th.offsetWidth);
|
||||||
|
ths.forEach((th, i) => {
|
||||||
|
const w = (Array.isArray(saved) && saved[i]) ? saved[i] : natural[i];
|
||||||
|
th.style.width = Math.max(60, w || 80) + 'px';
|
||||||
|
});
|
||||||
|
table.style.tableLayout = 'fixed';
|
||||||
|
const sync = () => {
|
||||||
|
const total = ths.reduce((s, t) => s + (parseFloat(t.style.width) || 0), 0);
|
||||||
|
table.style.width = total + 'px';
|
||||||
|
};
|
||||||
|
sync();
|
||||||
|
ths.forEach((th, i) => {
|
||||||
|
if (i >= ths.length - 1) return; // no handle on the last (trash) column
|
||||||
|
const res = document.createElement('div');
|
||||||
|
res.className = 'col-resizer';
|
||||||
|
th.appendChild(res);
|
||||||
|
res.addEventListener('mousedown', e => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
const startX = e.clientX, startW = th.offsetWidth;
|
||||||
|
document.body.style.cursor = 'col-resize';
|
||||||
|
const onMove = ev => {
|
||||||
|
th.style.width = Math.max(60, startW + (ev.clientX - startX)) + 'px';
|
||||||
|
sync();
|
||||||
|
};
|
||||||
|
const onUp = () => {
|
||||||
|
document.removeEventListener('mousemove', onMove);
|
||||||
|
document.removeEventListener('mouseup', onUp);
|
||||||
|
document.body.style.cursor = '';
|
||||||
|
try {
|
||||||
|
localStorage.setItem('calTableColWidths',
|
||||||
|
JSON.stringify(ths.map(t => Math.round(parseFloat(t.style.width) || 0))));
|
||||||
|
} catch {}
|
||||||
|
};
|
||||||
|
document.addEventListener('mousemove', onMove);
|
||||||
|
document.addEventListener('mouseup', onUp);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function renderCalendarTable() {
|
function renderCalendarTable() {
|
||||||
const container = document.getElementById('cal-settings-table');
|
const container = document.getElementById('cal-settings-table');
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
@@ -3880,6 +3929,8 @@ function renderCalendarTable() {
|
|||||||
<tbody>${rows}</tbody>
|
<tbody>${rows}</tbody>
|
||||||
</table>`;
|
</table>`;
|
||||||
|
|
||||||
|
initResizableCalTable(container.querySelector('.cal-manage-table'));
|
||||||
|
|
||||||
// Visibility eye toggle
|
// Visibility eye toggle
|
||||||
container.querySelectorAll('.ct-eye[data-ct-hid]').forEach(btn => {
|
container.querySelectorAll('.ct-eye[data-ct-hid]').forEach(btn => {
|
||||||
btn.addEventListener('click', async () => {
|
btn.addEventListener('click', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user