Add week planner entry editing popups
This commit is contained in:
@@ -1583,6 +1583,17 @@ legend {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.plan-chip.is-editable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.plan-chip.is-editable:hover {
|
||||
border-color: color-mix(in srgb, var(--accent) 34%, var(--line) 66%);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.7),
|
||||
0 10px 22px rgba(94, 68, 49, 0.12);
|
||||
}
|
||||
|
||||
.plan-chip:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
@@ -1602,6 +1613,55 @@ legend {
|
||||
padding: 0.55rem 0.85rem;
|
||||
}
|
||||
|
||||
.week-entry-dialog {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
max-width: min(34rem, calc(100vw - 2rem));
|
||||
width: min(34rem, calc(100vw - 2rem));
|
||||
}
|
||||
|
||||
.week-entry-dialog::backdrop {
|
||||
background: rgba(29, 22, 19, 0.54);
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
|
||||
.week-entry-dialog-card {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
padding: 1.1rem;
|
||||
border-radius: 22px;
|
||||
border: 1px solid var(--line);
|
||||
background: color-mix(in srgb, var(--surface) 98%, #fff 2%);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.week-entry-dialog-head {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 0.85rem;
|
||||
}
|
||||
|
||||
.week-entry-dialog-head h3 {
|
||||
margin: 0 0 0.2rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.week-entry-dialog-head p {
|
||||
margin: 0;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.week-entry-dialog-actions {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.week-entry-remove-form {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.plan-chip small,
|
||||
.week-slot-empty {
|
||||
color: var(--muted);
|
||||
@@ -1687,6 +1747,13 @@ legend {
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .plan-chip.is-editable:hover {
|
||||
border-color: rgba(243, 177, 125, 0.3);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.06),
|
||||
0 12px 26px rgba(0, 0, 0, 0.24);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .week-slot-copy {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-color: rgba(243, 177, 125, 0.12);
|
||||
@@ -1701,6 +1768,12 @@ legend {
|
||||
border-color: rgba(243, 177, 125, 0.16);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .week-entry-dialog-card {
|
||||
background: rgba(43, 37, 35, 0.98);
|
||||
border-color: rgba(243, 177, 125, 0.14);
|
||||
box-shadow: 0 24px 50px rgba(0, 0, 0, 0.34);
|
||||
}
|
||||
|
||||
.flash-stack {
|
||||
display: grid;
|
||||
gap: 0.7rem;
|
||||
|
||||
@@ -95,12 +95,14 @@
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
rememberScroll();
|
||||
if (result.redirect_url) {
|
||||
window.location.href = result.redirect_url;
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
} catch (_error) {
|
||||
rememberScroll();
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
@@ -196,6 +198,72 @@
|
||||
});
|
||||
};
|
||||
|
||||
const initWeekEntryDialogs = () => {
|
||||
const board = document.querySelector(".week-board");
|
||||
if (!board) return;
|
||||
|
||||
const openDialog = (trigger) => {
|
||||
const dialogId = trigger.getAttribute("data-week-entry-dialog-id");
|
||||
if (!dialogId) return;
|
||||
const dialog = document.getElementById(dialogId);
|
||||
if (!(dialog instanceof HTMLDialogElement)) return;
|
||||
if (!dialog.open) {
|
||||
dialog.showModal();
|
||||
}
|
||||
};
|
||||
|
||||
board.querySelectorAll("[data-week-entry-open]").forEach((entry) => {
|
||||
entry.addEventListener("click", (event) => {
|
||||
if (event.target instanceof Element && event.target.closest("button, a, input, select, textarea, label, form")) {
|
||||
return;
|
||||
}
|
||||
openDialog(entry);
|
||||
});
|
||||
|
||||
entry.addEventListener("keydown", (event) => {
|
||||
if (event.key !== "Enter" && event.key !== " ") return;
|
||||
event.preventDefault();
|
||||
openDialog(entry);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll(".week-entry-dialog").forEach((dialog) => {
|
||||
if (!(dialog instanceof HTMLDialogElement)) return;
|
||||
|
||||
dialog.addEventListener("click", (event) => {
|
||||
const rect = dialog.getBoundingClientRect();
|
||||
const clickedInside =
|
||||
rect.top <= event.clientY &&
|
||||
event.clientY <= rect.top + rect.height &&
|
||||
rect.left <= event.clientX &&
|
||||
event.clientX <= rect.left + rect.width;
|
||||
if (!clickedInside) {
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll("[data-week-entry-close]").forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const dialog = button.closest(".week-entry-dialog");
|
||||
if (dialog instanceof HTMLDialogElement) {
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll(".js-week-entry-submit").forEach((form) => {
|
||||
form.addEventListener("submit", async (event) => {
|
||||
event.preventDefault();
|
||||
try {
|
||||
await postAndRefreshInPlace(form);
|
||||
} catch (_error) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const syncActionContainerVisibility = (container) => {
|
||||
if (!(container instanceof HTMLElement)) return;
|
||||
const hasVisibleButtons = Array.from(container.querySelectorAll("button")).some((button) => {
|
||||
@@ -285,6 +353,7 @@
|
||||
initWeekDragAndDrop();
|
||||
initWeekCopyForward();
|
||||
initWeekSlotPicker();
|
||||
initWeekEntryDialogs();
|
||||
initDaySnackReveal();
|
||||
initWeekSnackReveal();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user