feat: add soft delete and media tab for user attachments with admin restore

This commit is contained in:
2026-06-11 18:52:56 +00:00
parent c74228bc6c
commit 3862958fae
40 changed files with 1549 additions and 81 deletions
@@ -0,0 +1,71 @@
// retoor <retoor@molodetz.nl>
import { Component } from "./Component.js";
export class AppLightbox extends Component {
connectedCallback() {
if (this._built) {
return;
}
this._built = true;
this.lastFocus = null;
this.bodyOverflow = "";
this.build();
this.bind();
}
build() {
const overlay = document.createElement("div");
overlay.className = "lightbox-overlay";
overlay.setAttribute("role", "dialog");
overlay.setAttribute("aria-modal", "true");
overlay.innerHTML =
'<button type="button" class="lightbox-close" aria-label="Close">&times;</button>' +
'<img class="lightbox-image" src="" alt="">';
this.appendChild(overlay);
this.overlay = overlay;
this.image = overlay.querySelector(".lightbox-image");
this.closeBtn = overlay.querySelector(".lightbox-close");
}
bind() {
this.overlay.addEventListener("click", (e) => {
if (e.target !== this.image) this.close();
});
this.closeBtn.addEventListener("click", () => this.close());
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && this.overlay.classList.contains("visible")) {
e.preventDefault();
this.close();
}
});
document.addEventListener("click", (e) => {
const thumb = e.target.closest("img[data-lightbox]");
if (!thumb || thumb.closest("a")) return;
e.preventDefault();
this.open(thumb.dataset.full || thumb.currentSrc || thumb.src, { alt: thumb.alt });
});
}
open(src, options) {
const opts = options || {};
if (!src) return;
this.image.src = src;
this.image.alt = opts.alt || "";
this.lastFocus = document.activeElement;
this.bodyOverflow = document.body.style.overflow;
document.body.style.overflow = "hidden";
this.overlay.classList.add("visible");
setTimeout(() => this.closeBtn.focus(), 20);
}
close() {
this.overlay.classList.remove("visible");
this.image.src = "";
document.body.style.overflow = this.bodyOverflow;
if (this.lastFocus && this.lastFocus.focus) this.lastFocus.focus();
}
}
customElements.define("dp-lightbox", AppLightbox);