From cad1655bfa52f545e63eb1cec540a0a1c148646a Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Tue, 30 Apr 2024 17:22:04 +0200 Subject: [PATCH] Allow dragging plugins directly to the end of the order machine --- CHANGELOG.rst | 2 ++ .../static/content_editor/content_editor.css | 4 +++ .../static/content_editor/content_editor.js | 32 ++++++++++++++----- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fa175017..473dd382 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,8 @@ Next version - Removed the maximum height from content editor inlines. - Started showing the target indicator again when dragging over collapsed plugins. +- Allowed dragging plugins to positions *after* existing plugins, not just + *before*. This allows dragging a plugin directly to the end, finally. 6.4 (2024-02-16) diff --git a/content_editor/static/content_editor/content_editor.css b/content_editor/static/content_editor/content_editor.css index 0dfc71f3..8bcf1978 100644 --- a/content_editor/static/content_editor/content_editor.css +++ b/content_editor/static/content_editor/content_editor.css @@ -321,6 +321,10 @@ h3[draggable] { height: 4px; background: #79aec8; } +.fs-dragover--after::before { + top: auto; + bottom: -8px; +} .fs-dragover::after { /* Cover fieldset with an overlay so that widgets do not swallow events */ diff --git a/content_editor/static/content_editor/content_editor.js b/content_editor/static/content_editor/content_editor.js index df0272ef..9763e9cf 100644 --- a/content_editor/static/content_editor/content_editor.js +++ b/content_editor/static/content_editor/content_editor.js @@ -166,6 +166,12 @@ django.jQuery(function ($) { return result })() + function shouldInsertAfter(inline, clientY) { + const rect = inline.getBoundingClientRect() + const yMid = rect.y + rect.height / 2 + 5 // Compensate for margin + return clientY > yMid + } + function ensureDraggable(arg) { if (arg.hasClass("empty-form") || arg.hasClass("fs-draggable")) return @@ -201,7 +207,12 @@ django.jQuery(function ($) { if (window.__fs_dragging) { e.preventDefault() $(".fs-dragover").removeClass("fs-dragover") - e.target.closest(".inline-related").classList.add("fs-dragover") + const inline = e.target.closest(".inline-related") + inline.classList.add("fs-dragover") + inline.classList.toggle( + "fs-dragover--after", + shouldInsertAfter(inline, e.clientY), + ) } }, true, @@ -209,13 +220,14 @@ django.jQuery(function ($) { inline.addEventListener("drop", function (e) { if (window.__fs_dragging) { e.preventDefault() - const before = e.target.closest(".inline-related") + const inline = e.target.closest(".inline-related") const toMove = qsa(".order-machine .inline-related.selected").map( (inline) => [inline, +inline.style.order], ) - toMove.sort((a, b) => a[1] - b[1]) + const orAfter = shouldInsertAfter(inline, e.clientY) + toMove.sort((a, b) => (orAfter ? -1 : 1) * (a[1] - b[1])) toMove.forEach((row) => { - insertBefore(row[0], before) + insertAdjacent(row[0], inline, orAfter) row[0].classList.remove("selected") }) window.__fs_dragging = null @@ -383,14 +395,18 @@ django.jQuery(function ($) { $row.css("order", ordering) } - function insertBefore(row, before) { - const beforeOrdering = +qs(".field-ordering input", before).value, + function insertAdjacent(row, inline, after = false) { + const inlineOrdering = +qs(".field-ordering input", inline).value, beforeRows = [], afterRows = [] orderMachine.find(".inline-related:not(.empty-form)").each(function () { const thisOrderingField = qs(".field-ordering input", this) if (this != row && !isNaN(+thisOrderingField.value)) { - if (+thisOrderingField.value >= beforeOrdering) { + if ( + after + ? +thisOrderingField.value > inlineOrdering + : +thisOrderingField.value >= inlineOrdering + ) { afterRows.push([this, thisOrderingField]) } else { beforeRows.push([this, thisOrderingField]) @@ -474,7 +490,7 @@ django.jQuery(function ($) { machineEmptyMessage.addClass("hidden") if (ContentEditor._insertBefore) { - insertBefore($row[0], ContentEditor._insertBefore) + insertAdjacent($row[0], ContentEditor._insertBefore) ContentEditor._insertBefore = null }