Enhance calendar duty display and tooltip functionality
- Updated the calendar rendering to use a duty marker with improved accessibility attributes for duty names and titles. - Introduced a new function `bindDutyMarkerTooltips` to display tooltips with duty names on hover over duty markers. - Enhanced CSS styles for duty markers to improve visibility and user interaction. - Ensured tooltips are dynamically positioned and hidden appropriately to enhance user experience.
This commit is contained in:
@@ -204,9 +204,11 @@
|
|||||||
|
|
||||||
const cell = document.createElement("div");
|
const cell = document.createElement("div");
|
||||||
cell.className = "day" + (isOther ? " other-month" : "") + (isToday ? " today" : "") + (dayDuties.length ? " has-duty" : "") + (hasEvent ? " holiday" : "");
|
cell.className = "day" + (isOther ? " other-month" : "") + (isToday ? " today" : "") + (dayDuties.length ? " has-duty" : "") + (hasEvent ? " holiday" : "");
|
||||||
|
const dutyNamesAttr = dayDuties.length ? escapeHtml(dayDuties.map(function (x) { return x.full_name; }).join("\n")) : "";
|
||||||
|
const dutyTitleAttr = dayDuties.length ? escapeHtml(dayDuties.map(function (x) { return x.full_name; }).join(", ")) : "";
|
||||||
cell.innerHTML =
|
cell.innerHTML =
|
||||||
"<span class=\"num\">" + d.getDate() + "</span>" +
|
"<span class=\"num\">" + d.getDate() + "</span>" +
|
||||||
(dayDuties.length ? "<span class=\"day-duties\">" + dayDuties.map(function (x) { return escapeHtml(x.full_name); }).join(", ") + "</span>" : "") +
|
(dayDuties.length ? "<span class=\"duty-marker\" data-duty-names=\"" + dutyNamesAttr + "\" title=\"" + dutyTitleAttr + "\" aria-label=\"Дежурные\">Д</span>" : "") +
|
||||||
(hasEvent ? "<button type=\"button\" class=\"info-btn\" aria-label=\"Информация о дне\" data-summary=\"" + escapeHtml(eventSummaries.join("\n")) + "\">i</button>" : "");
|
(hasEvent ? "<button type=\"button\" class=\"info-btn\" aria-label=\"Информация о дне\" data-summary=\"" + escapeHtml(eventSummaries.join("\n")) + "\">i</button>" : "");
|
||||||
calendarEl.appendChild(cell);
|
calendarEl.appendChild(cell);
|
||||||
d.setDate(d.getDate() + 1);
|
d.setDate(d.getDate() + 1);
|
||||||
@@ -214,6 +216,7 @@
|
|||||||
|
|
||||||
monthTitleEl.textContent = MONTHS[month] + " " + year;
|
monthTitleEl.textContent = MONTHS[month] + " " + year;
|
||||||
bindInfoButtonTooltips();
|
bindInfoButtonTooltips();
|
||||||
|
bindDutyMarkerTooltips();
|
||||||
}
|
}
|
||||||
|
|
||||||
function positionHint(hintEl, btnRect) {
|
function positionHint(hintEl, btnRect) {
|
||||||
@@ -298,6 +301,38 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bindDutyMarkerTooltips() {
|
||||||
|
var hintEl = document.getElementById("dutyMarkerHint");
|
||||||
|
if (!hintEl) {
|
||||||
|
hintEl = document.createElement("div");
|
||||||
|
hintEl.id = "dutyMarkerHint";
|
||||||
|
hintEl.className = "calendar-event-hint";
|
||||||
|
hintEl.setAttribute("role", "tooltip");
|
||||||
|
hintEl.hidden = true;
|
||||||
|
document.body.appendChild(hintEl);
|
||||||
|
}
|
||||||
|
var hideTimeout = null;
|
||||||
|
calendarEl.querySelectorAll(".duty-marker").forEach(function (marker) {
|
||||||
|
marker.addEventListener("mouseenter", function () {
|
||||||
|
if (hideTimeout) {
|
||||||
|
clearTimeout(hideTimeout);
|
||||||
|
hideTimeout = null;
|
||||||
|
}
|
||||||
|
var names = marker.getAttribute("data-duty-names") || "";
|
||||||
|
hintEl.textContent = names;
|
||||||
|
var rect = marker.getBoundingClientRect();
|
||||||
|
positionHint(hintEl, rect);
|
||||||
|
hintEl.hidden = false;
|
||||||
|
});
|
||||||
|
marker.addEventListener("mouseleave", function () {
|
||||||
|
hideTimeout = setTimeout(function () {
|
||||||
|
hintEl.hidden = true;
|
||||||
|
hideTimeout = null;
|
||||||
|
}, 150);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function renderDutyList(duties) {
|
function renderDutyList(duties) {
|
||||||
if (duties.length === 0) {
|
if (duties.length === 0) {
|
||||||
dutyListEl.innerHTML = "<p class=\"muted\">В этом месяце дежурств нет.</p>";
|
dutyListEl.innerHTML = "<p class=\"muted\">В этом месяце дежурств нет.</p>";
|
||||||
|
|||||||
@@ -90,6 +90,9 @@ body {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
background: var(--surface);
|
background: var(--surface);
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.day.other-month {
|
.day.other-month {
|
||||||
@@ -161,14 +164,19 @@ body {
|
|||||||
transform: none;
|
transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.day-duties {
|
.duty-marker {
|
||||||
font-size: 0.6rem;
|
display: inline-flex;
|
||||||
color: var(--duty);
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
max-width: 100%;
|
font-size: 0.65rem;
|
||||||
overflow: hidden;
|
font-weight: 700;
|
||||||
text-overflow: ellipsis;
|
color: var(--duty);
|
||||||
white-space: nowrap;
|
background: rgba(158, 206, 106, 0.25);
|
||||||
|
border-radius: 50%;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.duty-list {
|
.duty-list {
|
||||||
|
|||||||
Reference in New Issue
Block a user