Merge branch 'dev'
CI/CD / deploy (push) Successful in 2m5s
Details
CI/CD / deploy (push) Successful in 2m5s
Details
This commit is contained in:
commit
8cb6ca838e
|
|
@ -1689,11 +1689,12 @@ class FolkCalendarView extends HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute row assignments for overlapping horizontal events
|
// Compute row assignments for overlapping horizontal events
|
||||||
|
const MIN_DH_INTERVAL = Math.ceil(60 / HOUR_WIDTH * 60); // min display width (60px) → min interval
|
||||||
const dhIntervals = timed.map(ev => {
|
const dhIntervals = timed.map(ev => {
|
||||||
const s = new Date(ev.start_time), e = new Date(ev.end_time);
|
const s = new Date(ev.start_time), e = new Date(ev.end_time);
|
||||||
const startMin = s.getHours() * 60 + s.getMinutes();
|
const startMin = s.getHours() * 60 + s.getMinutes();
|
||||||
const endMin = e.getHours() * 60 + e.getMinutes();
|
const endMin = e.getHours() * 60 + e.getMinutes();
|
||||||
return { startMin, endMin: Math.max(endMin, startMin + 30) };
|
return { startMin, endMin: Math.max(endMin, startMin + MIN_DH_INTERVAL) };
|
||||||
});
|
});
|
||||||
const dhLayout = this.computeEventColumns(dhIntervals);
|
const dhLayout = this.computeEventColumns(dhIntervals);
|
||||||
const DH_ROW_HEIGHT = 56; // min-height 48 + 8px gap
|
const DH_ROW_HEIGHT = 56; // min-height 48 + 8px gap
|
||||||
|
|
@ -2152,7 +2153,9 @@ class FolkCalendarView extends HTMLElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let eventsOverlay = "";
|
// Build per-day event overlays (grid-aligned to avoid calc() rounding vs 1fr drift)
|
||||||
|
const MIN_INTERVAL_WEEK = Math.ceil(18 / HOUR_HEIGHT * 60); // min display height → min interval
|
||||||
|
const dayOverlays: string[] = [];
|
||||||
for (let i = 0; i < 7; i++) {
|
for (let i = 0; i < 7; i++) {
|
||||||
const ds = this.dateStr(days[i]);
|
const ds = this.dateStr(days[i]);
|
||||||
const dayTimed = this.getEventsForDate(ds).filter(ev => {
|
const dayTimed = this.getEventsForDate(ds).filter(ev => {
|
||||||
|
|
@ -2160,15 +2163,15 @@ class FolkCalendarView extends HTMLElement {
|
||||||
return (en.getTime() - s.getTime()) < 86400000;
|
return (en.getTime() - s.getTime()) < 86400000;
|
||||||
}).sort((a, b) => a.start_time.localeCompare(b.start_time));
|
}).sort((a, b) => a.start_time.localeCompare(b.start_time));
|
||||||
|
|
||||||
// Compute sub-columns for overlapping events within this day
|
|
||||||
const intervals = dayTimed.map(ev => {
|
const intervals = dayTimed.map(ev => {
|
||||||
const s = new Date(ev.start_time), e = new Date(ev.end_time);
|
const s = new Date(ev.start_time), e = new Date(ev.end_time);
|
||||||
const startMin = s.getHours() * 60 + s.getMinutes();
|
const startMin = s.getHours() * 60 + s.getMinutes();
|
||||||
const endMin = e.getHours() * 60 + e.getMinutes();
|
const endMin = e.getHours() * 60 + e.getMinutes();
|
||||||
return { startMin, endMin: Math.max(endMin, startMin + 20) };
|
return { startMin, endMin: Math.max(endMin, startMin + MIN_INTERVAL_WEEK) };
|
||||||
});
|
});
|
||||||
const dayLayout = this.computeEventColumns(intervals);
|
const dayLayout = this.computeEventColumns(intervals);
|
||||||
|
|
||||||
|
let dayHtml = "";
|
||||||
for (let j = 0; j < dayTimed.length; j++) {
|
for (let j = 0; j < dayTimed.length; j++) {
|
||||||
const ev = dayTimed[j];
|
const ev = dayTimed[j];
|
||||||
const { startMin, endMin } = intervals[j];
|
const { startMin, endMin } = intervals[j];
|
||||||
|
|
@ -2177,21 +2180,28 @@ class FolkCalendarView extends HTMLElement {
|
||||||
const topPx = ((startMin - START_HOUR * 60) / 60) * HOUR_HEIGHT;
|
const topPx = ((startMin - START_HOUR * 60) / 60) * HOUR_HEIGHT;
|
||||||
const heightPx = Math.max((duration / 60) * HOUR_HEIGHT, 18);
|
const heightPx = Math.max((duration / 60) * HOUR_HEIGHT, 18);
|
||||||
const es = this.getEventStyles(ev);
|
const es = this.getEventStyles(ev);
|
||||||
const colLeft = `calc(44px + ${i} * ((100% - 44px) / 7) + 2px + ${col} * ((100% - 44px) / 7 - 4px) / ${totalCols})`;
|
const evLeft = totalCols > 1 ? `calc(${(col / totalCols * 100).toFixed(2)}% + 1px)` : "1px";
|
||||||
const colWidth = `calc(((100% - 44px) / 7 - 4px) / ${totalCols} - 1px)`;
|
const evWidth = totalCols > 1 ? `calc(${(100 / totalCols).toFixed(2)}% - 2px)` : "calc(100% - 2px)";
|
||||||
const showMeta = heightPx >= 36;
|
const showMeta = heightPx >= 36;
|
||||||
const timeStr = `${this.formatTime(ev.start_time)}\u2013${this.formatTime(ev.end_time)}`;
|
const timeStr = `${this.formatTime(ev.start_time)}\u2013${this.formatTime(ev.end_time)}`;
|
||||||
const locName = ev.location_name ? this.esc(ev.location_name) : "";
|
const locName = ev.location_name ? this.esc(ev.location_name) : "";
|
||||||
const virtualBadge = ev.is_virtual ? `<span class="wk-virtual" title="Virtual">\u{1F4BB}</span>` : "";
|
const virtualBadge = ev.is_virtual ? `<span class="wk-virtual" title="Virtual">\u{1F4BB}</span>` : "";
|
||||||
eventsOverlay += `<div class="week-event" data-event-id="${ev.id}" style="
|
dayHtml += `<div class="week-event" data-event-id="${ev.id}" style="
|
||||||
top:${topPx}px;height:${heightPx}px;left:${colLeft};width:${colWidth};
|
top:${topPx}px;height:${heightPx}px;left:${evLeft};width:${evWidth};
|
||||||
background:${es.bgColor};border-left-color:${ev.source_color || "#6366f1"};border-left-style:${es.borderStyle};opacity:${es.opacity}">
|
background:${es.bgColor};border-left-color:${ev.source_color || "#6366f1"};border-left-style:${es.borderStyle};opacity:${es.opacity}">
|
||||||
<div class="week-event-title">${virtualBadge}${this.esc(ev.title)}</div>
|
<div class="week-event-title">${virtualBadge}${this.esc(ev.title)}</div>
|
||||||
${showMeta ? `<div class="week-event-meta"><span class="week-event-time">${timeStr}</span>${locName ? `<span class="week-event-loc">${locName}</span>` : ""}</div>` : ""}
|
${showMeta ? `<div class="week-event-meta"><span class="week-event-time">${timeStr}</span>${locName ? `<span class="week-event-loc">${locName}</span>` : ""}</div>` : ""}
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
dayOverlays.push(dayHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Grid-aligned overlay mirrors week-grid columns exactly (no calc drift)
|
||||||
|
const overlayDivs = dayOverlays.map(h =>
|
||||||
|
`<div style="position:relative;pointer-events:auto;">${h}</div>`
|
||||||
|
).join("");
|
||||||
|
const eventsOverlay = `<div style="position:absolute;inset:0;display:grid;grid-template-columns:44px repeat(7,1fr);pointer-events:none;"><div></div>${overlayDivs}</div>`;
|
||||||
|
|
||||||
let nowHtml = "";
|
let nowHtml = "";
|
||||||
const nowDay = days.findIndex(day => this.dateStr(day) === todayStr);
|
const nowDay = days.findIndex(day => this.dateStr(day) === todayStr);
|
||||||
if (nowDay >= 0) {
|
if (nowDay >= 0) {
|
||||||
|
|
@ -2205,9 +2215,11 @@ class FolkCalendarView extends HTMLElement {
|
||||||
return `
|
return `
|
||||||
<div class="week-view">
|
<div class="week-view">
|
||||||
<div class="week-header">${headerHtml}</div>
|
<div class="week-header">${headerHtml}</div>
|
||||||
<div style="position:relative;overflow-y:auto;max-height:600px;">
|
<div style="overflow-y:auto;max-height:600px;">
|
||||||
<div class="week-grid" style="position:relative;height:${totalHeight}px">${gridHtml}</div>
|
<div style="position:relative;height:${totalHeight}px;">
|
||||||
${eventsOverlay}${nowHtml}
|
<div class="week-grid" style="height:100%">${gridHtml}</div>
|
||||||
|
${eventsOverlay}${nowHtml}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue