122 lines
4.5 KiB
HTML
122 lines
4.5 KiB
HTML
{# GET /admin/tables/presentation — crate::pages::admin::table_definition::ui::PresentationPage #}
|
|
{% extends "ui/base.html" %}
|
|
|
|
{% block title %}{{ nav.tr("td-presentation-title") }}{% endblock %}
|
|
|
|
{% block head %}
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
let activeDrag = null;
|
|
|
|
function rows(editor) {
|
|
return Array.from(editor.querySelectorAll("[data-order-item]"));
|
|
}
|
|
|
|
function ids(editor) {
|
|
return rows(editor).map(function (row) { return row.dataset.columnId; });
|
|
}
|
|
|
|
function refresh(editor) {
|
|
rows(editor).forEach(function (row, index) {
|
|
row.querySelector(".order-position").textContent = index + 1;
|
|
});
|
|
|
|
const dirty = ids(editor).join(",") !== editor.dataset.originalOrder;
|
|
editor.classList.toggle("is-dirty", dirty);
|
|
editor.querySelector("[data-order-status]").textContent = dirty
|
|
? editor.dataset.dirtyText
|
|
: editor.dataset.cleanText;
|
|
editor.querySelector("[data-order-reset]").disabled = !dirty;
|
|
editor.querySelector("[data-order-save]").disabled = !dirty;
|
|
}
|
|
|
|
function initialise(root) {
|
|
root.querySelectorAll("[data-order-editor]").forEach(function (editor) {
|
|
editor.dataset.originalOrder = ids(editor).join(",");
|
|
refresh(editor);
|
|
});
|
|
}
|
|
|
|
function finishDrag(event) {
|
|
if (!activeDrag || (event.pointerId !== undefined && event.pointerId !== activeDrag.pointerId)) return;
|
|
activeDrag.row.classList.remove("is-dragging");
|
|
if (activeDrag.handle.hasPointerCapture(activeDrag.pointerId)) {
|
|
activeDrag.handle.releasePointerCapture(activeDrag.pointerId);
|
|
}
|
|
refresh(activeDrag.editor);
|
|
activeDrag = null;
|
|
}
|
|
|
|
document.addEventListener("pointerdown", function (event) {
|
|
const handle = event.target.closest("[data-drag-handle]");
|
|
if (!handle || (event.button !== undefined && event.button !== 0)) return;
|
|
|
|
const row = handle.closest("[data-order-item]");
|
|
activeDrag = {
|
|
editor: handle.closest("[data-order-editor]"),
|
|
handle: handle,
|
|
list: row.parentElement,
|
|
pointerId: event.pointerId,
|
|
row: row
|
|
};
|
|
handle.setPointerCapture(event.pointerId);
|
|
row.classList.add("is-dragging");
|
|
event.preventDefault();
|
|
});
|
|
|
|
document.addEventListener("pointermove", function (event) {
|
|
if (!activeDrag || event.pointerId !== activeDrag.pointerId) return;
|
|
const hovered = document.elementFromPoint(event.clientX, event.clientY);
|
|
const target = hovered && hovered.closest("[data-order-item]");
|
|
if (!target || target === activeDrag.row || target.parentElement !== activeDrag.list) return;
|
|
|
|
const before = event.clientY < target.getBoundingClientRect().top + target.offsetHeight / 2;
|
|
activeDrag.list.insertBefore(activeDrag.row, before ? target : target.nextElementSibling);
|
|
refresh(activeDrag.editor);
|
|
});
|
|
|
|
document.addEventListener("pointerup", finishDrag);
|
|
document.addEventListener("pointercancel", finishDrag);
|
|
|
|
document.addEventListener("keydown", function (event) {
|
|
const handle = event.target.closest("[data-drag-handle]");
|
|
if (!handle || (event.key !== "ArrowUp" && event.key !== "ArrowDown")) return;
|
|
|
|
const row = handle.closest("[data-order-item]");
|
|
const sibling = event.key === "ArrowUp" ? row.previousElementSibling : row.nextElementSibling;
|
|
if (!sibling) return;
|
|
if (event.key === "ArrowUp") row.parentElement.insertBefore(row, sibling);
|
|
else row.parentElement.insertBefore(sibling, row);
|
|
refresh(handle.closest("[data-order-editor]"));
|
|
event.preventDefault();
|
|
});
|
|
|
|
document.addEventListener("click", function (event) {
|
|
const reset = event.target.closest("[data-order-reset]");
|
|
if (!reset) return;
|
|
|
|
const editor = reset.closest("[data-order-editor]");
|
|
const byId = new Map(rows(editor).map(function (row) { return [row.dataset.columnId, row]; }));
|
|
const list = editor.querySelector("[data-order-list]");
|
|
editor.dataset.originalOrder.split(",").forEach(function (id) { list.appendChild(byId.get(id)); });
|
|
refresh(editor);
|
|
});
|
|
|
|
initialise(document);
|
|
document.body.addEventListener("htmx:afterSwap", function (event) {
|
|
initialise(event.detail.target);
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<main>
|
|
{% include "pages/admin/table_definition/context.html" %}
|
|
|
|
<div id="table-panel" aria-live="polite">
|
|
{% include "pages/admin/table_definition/presentation_panel.html" %}
|
|
</div>
|
|
</main>
|
|
{% endblock %}
|