From d41ee504caedbe858e24ab2a23c7a804454c64c8 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Sat, 18 Jul 2026 02:15:29 +0200 Subject: Add Trash affordances: cockpit, listing, dashboard entry nodes#show gains a Trash section on trashed nodes: provenance from the trash entry, a restore form whose parent picker pre-fills the old parent while it still lives, and permanent deletion. A Move-to-Trash button joins the status actions on living nodes. nodes#trashed lists trashed subtree roots with weight, provenance, and deletion; the dashboard housekeeping row links to it, and trash/destroy redirect there. Deletion from Trash now removes the whole subtree, deepest first, each node through a real destroy! so every per-node cascade runs -- amending the never-recursive rule for this one sanctioned path (both confirms state the count; the root entry carries destroyed_descendants). Bare Node#destroy still refuses children. --- public/javascripts/admin_interface.js | 4 ++++ public/javascripts/admin_search.js | 13 +++++++++++++ public/stylesheets/admin.css | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) (limited to 'public') diff --git a/public/javascripts/admin_interface.js b/public/javascripts/admin_interface.js index 3988016..c0e2d9c 100644 --- a/public/javascripts/admin_interface.js +++ b/public/javascripts/admin_interface.js @@ -57,6 +57,10 @@ $(document).ready(function () { move_to_search.initialize_search(); } + if ($("#restore_search_term").length != 0) { + restore_search.initialize_search(); + } + if ($("#event_node_search_term").length != 0) { event_search.initialize_search(); } diff --git a/public/javascripts/admin_search.js b/public/javascripts/admin_search.js index d135503..b53c931 100644 --- a/public/javascripts/admin_search.js +++ b/public/javascripts/admin_search.js @@ -262,6 +262,19 @@ move_to_search = { } }; +restore_search = { + initialize_search : function() { + initSearchPicker({ + inputSelector: "#restore_search_term", + resultsSelector: "#restore_search_results", + onSelect: function(node) { + $("#restore_search_term").val(node.title); + $("#parent_id").val(node.node_id); + } + }); + } +}; + event_search = { initialize_search : function() { initSearchPicker({ diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css index 82963dd..88fd84b 100644 --- a/public/stylesheets/admin.css +++ b/public/stylesheets/admin.css @@ -884,6 +884,10 @@ form.button_to button[type="submit"] { margin-top: -5px; } +.aligned_action_row .action_button.action_button_no_margin_top { + margin-top: 0; +} + /* ============================================================ Page editor / metadata forms ============================================================ */ @@ -1539,3 +1543,34 @@ div#image_browser ul li { font-size: smaller; color: #777; } + +/* ============================================================ + Trash section + ============================================================ */ + +.restore_form { + display: flex; + align-items: center; + gap: 8px; +} + +.restore_picker { + position: relative; +} + +.restore_picker input[type=text] { + width: 22em; +} + +.restore_picker .search_results { + position: absolute; + top: 100%; + left: 0; + right: 0; + z-index: 10; + background: #fff; + border: 1px solid #989898; + border-top: none; + max-height: 20em; + overflow-y: auto; +} -- cgit v1.3