From 61ee4f897a51711992cf0599412cfae96156455f Mon Sep 17 00:00:00 2001 From: Keith M Date: Mon, 10 Mar 2025 18:22:07 -0700 Subject: [PATCH 1/2] get table working --- .../javascripts/activeadmin_reorderable.js | 247 +++++++++++------- .../stylesheets/activeadmin_reorderable.scss | 57 +++- lib/active_admin/reorderable/dsl.rb | 47 +++- lib/active_admin/reorderable/table_methods.rb | 30 ++- .../views/index_as_reorderable_table.rb | 51 +++- .../views/reorderable_table_for.rb | 47 +++- lib/activeadmin_reorderable/engine.rb | 40 +++ 7 files changed, 400 insertions(+), 119 deletions(-) diff --git a/app/assets/javascripts/activeadmin_reorderable.js b/app/assets/javascripts/activeadmin_reorderable.js index 0f540af..548ecdb 100644 --- a/app/assets/javascripts/activeadmin_reorderable.js +++ b/app/assets/javascripts/activeadmin_reorderable.js @@ -1,116 +1,165 @@ -const setupReorderable = ({ table, onDragover, onDragEnd }) => { - const rows = table.getElementsByTagName('tbody')[0].rows - - let dragSrc = null - let srcIndex = null - - for (var i = 0; i < rows.length; i++) { - const row = rows[i] - const handle = row.querySelector(".reorder-handle") - - // Add draggable only when the handle is clicked, to prevent dragging from the rest of the row - handle.addEventListener("mousedown", () => row.setAttribute("draggable", "true")) - handle.addEventListener("mouseup", () => row.setAttribute("draggable", "false")) - - row.addEventListener("dragstart", (e) => { - e.dataTransfer.effectAllowed = "move" - - dragSrc = row - srcIndex = row.rowIndex - - // Apply styling a millisecond later, so the dragging image shows up correctly - setTimeout(() => { row.classList.add("dragged-row") }, 1) - }) - - row.addEventListener("dragover", (e) => { - e.preventDefault() - e.dataTransfer.dropEffect = "move" - - // If dragged to a new location, move the dragged row - if (dragSrc != row) { - const sourceIndex = dragSrc.rowIndex - const targetIndex = row.rowIndex +// ActiveAdmin Reorderable - JavaScript for drag-and-drop reordering +// Compatible with ActiveAdmin 4.0 and Importmap + +console.log( + "%c ACTIVEADMIN REORDERABLE LOADED - VERSION 1.0.0 ", + "background: #ff0000; color: #ffffff; font-size: 20px; font-weight: bold; padding: 10px;" +); + +console.log( + "%c ActiveAdmin Reorderable Loaded!", + "background: #222; color: #bada55; font-size: 16px;" +); + +document.addEventListener("DOMContentLoaded", function () { + initReorderable(); +}); + +function initReorderable() { + console.log("Initializing reorderable tables"); + + // Get all tables that might be reorderable + const tables = document.querySelectorAll("table.data-table"); + console.log(`Found ${tables.length} data tables`); + + // Find all reorder handles in the document + const allHandles = document.querySelectorAll(".reorder-handle"); + console.log(`Found ${allHandles.length} reorder handles in document`); + + tables.forEach(function (table) { + // Check if this table has reorder handles + const handles = table.querySelectorAll(".reorder-handle"); + if (handles.length > 0) { + console.log( + `Table has ${handles.length} reorder handles - initializing drag/drop` + ); + initTableDragDrop(table); + } + }); +} - if (sourceIndex < targetIndex) { - table.tBodies[0].insertBefore(dragSrc, row.nextSibling) +function initTableDragDrop(table) { + const tbody = table.querySelector("tbody"); + if (!tbody) return; + + const rows = tbody.querySelectorAll("tr"); + console.log(`Table has ${rows.length} rows`); + + let dragSrcRow = null; + + // Set up drag events for each row that has a handle + rows.forEach(function (row) { + const handle = row.querySelector(".reorder-handle"); + if (!handle) return; + + // Get the reorder URL from the handle's data attribute + const reorderUrl = handle.dataset.reorderUrl; + console.log(`Row ${row.id} has reorder URL: ${reorderUrl}`); + + if (!reorderUrl) { + console.warn(`Row ${row.id} is missing a reorder URL!`); + // Check all data attributes for debugging + console.log("Handle data attributes:", handle.dataset); + return; + } + + // Make the row draggable only when the handle is clicked + handle.addEventListener("mousedown", function () { + console.log(`Handle mousedown on row ${row.id}`); + row.draggable = true; + }); + + handle.addEventListener("mouseup", function () { + row.draggable = false; + }); + + // Set up drag start + row.addEventListener("dragstart", function (e) { + console.log(`Drag started on row ${row.id}`); + dragSrcRow = row; + e.dataTransfer.effectAllowed = "move"; + + // Add a class to style the dragged row + setTimeout(function () { + row.classList.add("dragged-row"); + }, 0); + }); + + // Handle drag over + row.addEventListener("dragover", function (e) { + if (!dragSrcRow) return; + + e.preventDefault(); + e.dataTransfer.dropEffect = "move"; + + if (dragSrcRow !== row) { + // Determine whether to insert before or after + const rect = row.getBoundingClientRect(); + const midpoint = rect.top + rect.height / 2; + + if (e.clientY < midpoint) { + tbody.insertBefore(dragSrcRow, row); } else { - table.tBodies[0].insertBefore(dragSrc, row) + tbody.insertBefore(dragSrcRow, row.nextSibling); } - onDragover(dragSrc) } - }) - - row.addEventListener("dragend", () => { - // Disable dragging, so only the handle can start the dragging again - row.setAttribute("draggable", "false") - row.classList.remove("dragged-row") + }); - if (srcIndex != row.rowIndex) { - onDragEnd(dragSrc) - } + // Handle drag end + row.addEventListener("dragend", function () { + console.log(`Drag ended on row ${row.id}`); + row.draggable = false; + row.classList.remove("dragged-row"); - dragSrc = null - srcIndex = null - }) - } -} + if (dragSrcRow) { + // Get the new position (1-indexed) + const allRows = tbody.querySelectorAll("tr"); + const newPosition = Array.from(allRows).indexOf(dragSrcRow) + 1; -const updateEvenOddClasses = (row, index) => { - row.classList.remove("odd") - row.classList.remove("even") + // Update the backend + updateRowPosition(reorderUrl, newPosition); - if ((index + 1) % 2 == 0) { - row.classList.add("even") - } else { - row.classList.add("odd") - } -} + // Update row classes (odd/even) + Array.from(allRows).forEach(function (r, i) { + r.classList.remove("odd", "even"); + r.classList.add(i % 2 === 0 ? "odd" : "even"); + }); -const updatePositionText = (row, index) => { - const position = row.querySelector(".position") - if (position) { - position.textContent = index - } + dragSrcRow = null; + } + }); + }); } -const updateBackend = (url, rowIndex) => { - let headers = { } +function updateRowPosition(url, position) { + console.log(`Updating row position: ${url} to position ${position}`); - const csrfElement = document.querySelector("meta[name=csrf-token]") - if (csrfElement) { - headers["X-CSRF-Token"] = csrfElement.getAttribute("content") - } else { - console.warn("Rails CSRF element not present. AJAX requests may fail due to CORS issues.") + // Get the CSRF token + const csrfToken = document + .querySelector("meta[name='csrf-token']") + ?.getAttribute("content"); + const headers = {}; + if (csrfToken) { + headers["X-CSRF-Token"] = csrfToken; } - const formData = new FormData() - formData.append("position", rowIndex) + // Create form data + const formData = new FormData(); + formData.append("position", position); - fetch(url, { method: "POST", headers, body: formData }) -} - -document.addEventListener("DOMContentLoaded", () => { - document.querySelectorAll("table.aa-reorderable").forEach((table) => { - setupReorderable({ - table, - onDragover: (_row) => { - const allRows = table.getElementsByTagName('tbody')[0].rows - - for (var i = 0; i < allRows.length; i++) { - const loopRow = allRows[i] - const index = i + 1 - updateEvenOddClasses(loopRow, index) - updatePositionText(loopRow, index) - } - }, - onDragEnd: (row) => { - const handle = row.querySelector(".reorder-handle") - const url = handle.dataset["reorderUrl"] - const allRows = table.getElementsByTagName('tbody')[0].rows - const rowIndex = Array.prototype.indexOf.call(allRows, row) - - updateBackend(url, rowIndex + 1) + // Send the request + fetch(url, { + method: "POST", + headers: headers, + body: formData, + }) + .then(function (response) { + if (!response.ok) { + throw new Error(`HTTP error ${response.status}`); } + console.log("Position updated successfully"); }) - }) -}) + .catch(function (error) { + console.error("Error updating position:", error); + }); +} diff --git a/app/assets/stylesheets/activeadmin_reorderable.scss b/app/assets/stylesheets/activeadmin_reorderable.scss index f19ceda..ab6f0a4 100644 --- a/app/assets/stylesheets/activeadmin_reorderable.scss +++ b/app/assets/stylesheets/activeadmin_reorderable.scss @@ -1,13 +1,60 @@ -@use "@activeadmin/activeadmin/src/scss/mixins/all" as *; - -.aa-reorderable { +/* Styles for both classic ActiveAdmin and ActiveAdmin 4.0 with Tailwind */ +.aa-reorderable, +[data-reorderable="true"], +.index-as-table { .reorder-handle { cursor: move; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 4px; + border-radius: 4px; + background-color: #f9fafb; + border: 1px solid #e5e7eb; - @include light-button; + &:hover { + background-color: #f3f4f6; + } } .dragged-row { - opacity: 0; + opacity: 0.5; + background-color: #f0f0f0 !important; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); + } +} + +/* Additional styles specific to ActiveAdmin 4.0 */ +.data-table { + .reorder-handle-col { + width: 30px; + min-width: 30px; + cursor: move; + vertical-align: middle; + } + + tr { + &[draggable="true"] { + cursor: move; + } } + + .reorder-handle { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 4px; + border-radius: 4px; + + &:hover { + background-color: #f0f0f0; + } + } +} + +/* Style the SVG icon inside the handle */ +.reorder-handle svg { + width: 16px; + height: 16px; + color: currentColor; } diff --git a/lib/active_admin/reorderable/dsl.rb b/lib/active_admin/reorderable/dsl.rb index 5066929..70c2bbe 100644 --- a/lib/active_admin/reorderable/dsl.rb +++ b/lib/active_admin/reorderable/dsl.rb @@ -1,16 +1,53 @@ module ActiveAdmin module Reorderable module DSL - private - - def reorderable(&block) - body = proc do + # In ActiveAdmin 4.0, we need a different approach + # This method is called on the resource DSL (ActiveAdmin.register) + def reorderable + # Log that we're registering the reorderable functionality + puts "REGISTERING REORDERABLE FOR #{self.class.name} ###############" + + # Add the member action for handling reordering via AJAX + member_action :reorder, method: :post do + puts "REORDER ACTION CALLED FOR #{resource.class.name}:#{resource.id} ###############" resource.insert_at(params[:position].to_i) head :ok end - member_action(:reorder, :method => :post, &block || body) + # Only available in AA4 + if defined?(::ActiveAdmin::Views::IndexTableFor) + # Add the reorder_column method to IndexTableFor + ::ActiveAdmin::Views::IndexTableFor.class_eval do + def reorder_column + column "", data: { column: 'reorder' }, class: "reorder-handle-col", sortable: false do |resource| + puts "RENDERING REORDER HANDLE FOR #{resource.class.name}:#{resource.id} ###############" + + # Get the URL for the reorder action + aa_resource = active_admin_namespace.resource_for(resource.class) + url = aa_resource.route_member_action_path(:reorder, resource) + + puts "REORDER URL: #{url.inspect} for resource ID #{resource.id.inspect} ###############" + + # Test both attribute formats + puts "GENERATING SPAN WITH data-reorder-url=#{url.inspect} ###############" + + # Render the handle with an SVG icon - ensure we're using valid HTML attributes + content_tag :span, + class: 'reorder-handle', + data: { reorder_url: url, reorder_id: resource.id }, + style: 'cursor: move; display: inline-flex; align-items: center; justify-content: center; padding: 4px;' do + raw(' + + ') + end + end + end + end + end end end end end + +# Include in the ResourceDSL +::ActiveAdmin::ResourceDSL.send(:include, ActiveAdmin::Reorderable::DSL) diff --git a/lib/active_admin/reorderable/table_methods.rb b/lib/active_admin/reorderable/table_methods.rb index 040c54e..9499c5c 100644 --- a/lib/active_admin/reorderable/table_methods.rb +++ b/lib/active_admin/reorderable/table_methods.rb @@ -3,7 +3,10 @@ module Reorderable module TableMethods def reorder_column - column '', :class => 'reorder-handle-col' do |resource| + puts "IN REORDER_COLUMN ###############" + # Add data attribute to help with debugging + column '', class: 'reorder-handle-col', data: { reorderable_handle: true } do |resource| + puts "RENDERING HANDLE FOR RESOURCE #{resource.id} ###############" reorder_handle_for(resource) end end @@ -11,18 +14,37 @@ def reorder_column private def reorder_handle_for(resource) + puts "IN REORDER_HANDLE_FOR #{resource.id} ###############" aa_resource = active_admin_namespace.resource_for(resource.class) url = aa_resource.route_member_action_path(:reorder, resource) - - span(reorder_handle_content, :class => 'reorder-handle', 'data-reorder-url' => url) + + puts "REORDER URL: #{url} ###############" + + # Create a handle that works with both classic AA and AA4 with Tailwind + span(reorder_handle_content, + class: 'reorder-handle', + 'data-reorder-url' => url, + 'data-reorder-id' => resource.id, + style: 'cursor: move; display: inline-block;' + ) end def reorder_handle_content - '≡≡'.html_safe + # SVG icon more compatible with Tailwind styling + ' + + '.html_safe end end + # Include the TableMethods in both the TableFor and new AA4 "standard" table ::ActiveAdmin::Views::TableFor.send(:include, TableMethods) + + # Attempt to detect and include in AA4's data table class if it exists + if defined?(::ActiveAdmin::Views::IndexAsTable::IndexTableFor) + puts "INCLUDING TABLE METHODS IN IndexAsTable::IndexTableFor ###############" + ::ActiveAdmin::Views::IndexAsTable::IndexTableFor.send(:include, TableMethods) + end end end diff --git a/lib/active_admin/views/index_as_reorderable_table.rb b/lib/active_admin/views/index_as_reorderable_table.rb index eb8a29e..871ab20 100644 --- a/lib/active_admin/views/index_as_reorderable_table.rb +++ b/lib/active_admin/views/index_as_reorderable_table.rb @@ -1,20 +1,65 @@ module ActiveAdmin module Views + # This class is just a placeholder/compatibility layer + # In ActiveAdmin 4.0, we're adding the reorder_column method directly to IndexTableFor class IndexAsReorderableTable < IndexAsTable - def self.index_name + puts "IN INDEX_NAME ###############" 'reorderable_table' end def build(page_presenter, collection) + puts "IN BUILD ###############" add_class 'aa-reorderable' + # Add data-reorderable attribute for easier JS selection with ActiveAdmin 4 + @table_options = { data: { reorderable: true } } super(page_presenter, collection) end def table_for(*args, &block) - insert_tag ReorderableTableFor, *args, &block + puts "IN TABLE_FOR ###############" + puts "ARGS: #{args.inspect} ###############" + puts "BLOCK GIVEN: #{block_given?} ###############" + + # Ensure the first column is a reorder handle + new_block = proc do + puts "INSIDE NEW BLOCK ###############" + # Try both methods of adding the reorder column + if respond_to?(:reorder_column) + puts "CALLING REORDER_COLUMN FROM TABLE_FOR ###############" + reorder_column + else + puts "ADDING MANUAL REORDER COLUMN ###############" + column '', class: 'reorder-handle-col' do |resource| + puts "RENDERING MANUAL HANDLE FOR #{resource.id} ###############" + span(' + + '.html_safe, + class: 'reorder-handle', + 'data-reorder-url' => active_admin_namespace.resource_for(resource.class).route_member_action_path(:reorder, resource), + 'data-reorder-id' => resource.id, + style: 'cursor: move; display: inline-block;' + ) + end + end + + # Call the original block + instance_eval(&block) if block + end + + # First try with our custom table component + begin + puts "TRYING TO INSERT REORDERABLE TABLE ###############" + tag = insert_tag ReorderableTableFor, *args, &new_block + puts "REORDERABLE TABLE INSERTED: #{tag.class.name} ###############" + tag + rescue => e + # If that fails, try with the standard AA4 table + puts "ERROR WITH REORDERABLE TABLE: #{e.message} ###############" + puts "TRYING WITH STANDARD TABLE ###############" + super(*args, &new_block) + end end - end end end diff --git a/lib/active_admin/views/reorderable_table_for.rb b/lib/active_admin/views/reorderable_table_for.rb index dc8aa05..da62f17 100644 --- a/lib/active_admin/views/reorderable_table_for.rb +++ b/lib/active_admin/views/reorderable_table_for.rb @@ -4,14 +4,55 @@ class ReorderableTableFor < IndexAsTable::IndexTableFor builder_method :reorderable_table_for def build(collection, options = {}, &block) - options[:class] = [options[:class], 'aa-reorderable'].compact.join(' ') - + puts "IN REORDERABLE_TABLE_FOR BUILD ###############" + # Add both classic and Tailwind-compatible classes + options[:class] = [options[:class], 'aa-reorderable', 'data-table'].compact.join(' ') + # Add data attribute for easier selection with modern JS + options[:data] ||= {} + options[:data][:reorderable] = true + + puts "COLLECTION CLASS: #{collection.class.name} ###############" + puts "OPTIONS: #{options.inspect} ###############" + super(collection, options) do + puts "CALLING REORDER_COLUMN ###############" reorder_column + puts "CALLING BLOCK ###############" block.call if block.present? end end - + end + + # Try to monkey-patch ActiveAdmin 4.0's table implementation if it exists + begin + puts "CHECKING FOR ActiveAdmin 4.0 TABLE CLASSES ###############" + aa4_table_classes = ActiveAdmin::Views.constants.select { |c| c.to_s.include?('Table') } + puts "FOUND TABLE CLASSES: #{aa4_table_classes.join(', ')} ###############" + + if defined?(::ActiveAdmin::Views::Table) + puts "FOUND ActiveAdmin::Views::Table, EXTENDING IT ###############" + class ::ActiveAdmin::Views::Table + def reorderable_column + puts "AA4 TABLE REORDERABLE_COLUMN CALLED ###############" + column '', class: 'reorder-handle-col', data: { reorderable_handle: true } do |resource| + puts "AA4 RENDERING HANDLE FOR RESOURCE #{resource.id} ###############" + aa_resource = active_admin_namespace.resource_for(resource.class) + url = aa_resource.route_member_action_path(:reorder, resource) + + span(' + + '.html_safe, + class: 'reorder-handle', + 'data-reorder-url' => url, + 'data-reorder-id' => resource.id, + style: 'cursor: move; display: inline-block;' + ) + end + end + end + end + rescue => e + puts "ERROR CHECKING FOR AA4 TABLES: #{e.message} ###############" end end end diff --git a/lib/activeadmin_reorderable/engine.rb b/lib/activeadmin_reorderable/engine.rb index 797890b..ec6f925 100644 --- a/lib/activeadmin_reorderable/engine.rb +++ b/lib/activeadmin_reorderable/engine.rb @@ -2,12 +2,52 @@ module ActiveadminReorderable class Engine < Rails::Engine + initializer "activeadmin_reorderable.precompile", group: :all do |app| + # Add assets to precompile for ActiveAdmin 3 and below + app.config.assets.precompile += %w(activeadmin_reorderable.js activeadmin_reorderable.css) + end + initializer "activeadmin_reorderable.importmap", before: "importmap" do |app| # Skip if importmap-rails is not installed next unless app.config.respond_to?(:importmap) + # Add to importmap for ActiveAdmin 4 app.config.importmap.paths << Engine.root.join("config/importmap.rb") app.config.importmap.cache_sweepers << Engine.root.join("app/assets/javascripts") + + puts "Added activeadmin_reorderable to importmap paths ###############" + end + + initializer "activeadmin_reorderable.load_views", after: "active_admin.load_views" do + puts "ActiveAdmin Reorderable: Loading views" + ActiveAdmin.application.load_paths.unshift(Engine.root.join("lib/active_admin/views").to_s) + end + + initializer "activeadmin_reorderable.register_plugin", after: "active_admin.register_plugin" do + puts "ActiveAdmin Reorderable: Registering plugin" + require File.expand_path("../../active_admin/reorderable/dsl", __FILE__) + require File.expand_path("../../active_admin/reorderable/table_methods", __FILE__) + require File.expand_path("../../active_admin/views/index_as_reorderable_table", __FILE__) + require File.expand_path("../../active_admin/views/reorderable_table_for", __FILE__) + end + + # Setup ActiveAdmin importmap integration + initializer "activeadmin_reorderable.setup_importmap", after: "activeadmin.importmap" do + puts "Setting up ActiveAdmin importmap for activeadmin_reorderable ###############" + + # Make sure ActiveAdmin knows about our JavaScript + if defined?(ActiveAdmin.importmap) + js_path = Engine.root.join("app/assets/javascripts/activeadmin_reorderable.js") + + if File.exist?(js_path) + puts "Registering activeadmin_reorderable.js with ActiveAdmin importmap ###############" + ActiveAdmin.importmap.pin "activeadmin_reorderable", to: "activeadmin_reorderable.js", preload: true + else + puts "WARNING: Could not find #{js_path} ###############" + end + else + puts "WARNING: ActiveAdmin.importmap not defined ###############" + end end end end From dc3b7ff824ce8219680421543a88918e8071cf9b Mon Sep 17 00:00:00 2001 From: Keith M Date: Thu, 13 Mar 2025 16:38:06 -0700 Subject: [PATCH 2/2] code cleanup --- .../javascripts/activeadmin_reorderable.js | 27 ------------------- lib/active_admin/reorderable/dsl.rb | 7 ----- lib/active_admin/reorderable/table_methods.rb | 6 ----- .../views/index_as_reorderable_table.rb | 14 ---------- .../views/reorderable_table_for.rb | 13 --------- lib/activeadmin_reorderable/engine.rb | 4 --- 6 files changed, 71 deletions(-) diff --git a/app/assets/javascripts/activeadmin_reorderable.js b/app/assets/javascripts/activeadmin_reorderable.js index 548ecdb..83901c6 100644 --- a/app/assets/javascripts/activeadmin_reorderable.js +++ b/app/assets/javascripts/activeadmin_reorderable.js @@ -1,38 +1,20 @@ // ActiveAdmin Reorderable - JavaScript for drag-and-drop reordering // Compatible with ActiveAdmin 4.0 and Importmap - -console.log( - "%c ACTIVEADMIN REORDERABLE LOADED - VERSION 1.0.0 ", - "background: #ff0000; color: #ffffff; font-size: 20px; font-weight: bold; padding: 10px;" -); - -console.log( - "%c ActiveAdmin Reorderable Loaded!", - "background: #222; color: #bada55; font-size: 16px;" -); - document.addEventListener("DOMContentLoaded", function () { initReorderable(); }); function initReorderable() { - console.log("Initializing reorderable tables"); - // Get all tables that might be reorderable const tables = document.querySelectorAll("table.data-table"); - console.log(`Found ${tables.length} data tables`); // Find all reorder handles in the document const allHandles = document.querySelectorAll(".reorder-handle"); - console.log(`Found ${allHandles.length} reorder handles in document`); tables.forEach(function (table) { // Check if this table has reorder handles const handles = table.querySelectorAll(".reorder-handle"); if (handles.length > 0) { - console.log( - `Table has ${handles.length} reorder handles - initializing drag/drop` - ); initTableDragDrop(table); } }); @@ -43,7 +25,6 @@ function initTableDragDrop(table) { if (!tbody) return; const rows = tbody.querySelectorAll("tr"); - console.log(`Table has ${rows.length} rows`); let dragSrcRow = null; @@ -54,18 +35,15 @@ function initTableDragDrop(table) { // Get the reorder URL from the handle's data attribute const reorderUrl = handle.dataset.reorderUrl; - console.log(`Row ${row.id} has reorder URL: ${reorderUrl}`); if (!reorderUrl) { console.warn(`Row ${row.id} is missing a reorder URL!`); // Check all data attributes for debugging - console.log("Handle data attributes:", handle.dataset); return; } // Make the row draggable only when the handle is clicked handle.addEventListener("mousedown", function () { - console.log(`Handle mousedown on row ${row.id}`); row.draggable = true; }); @@ -75,7 +53,6 @@ function initTableDragDrop(table) { // Set up drag start row.addEventListener("dragstart", function (e) { - console.log(`Drag started on row ${row.id}`); dragSrcRow = row; e.dataTransfer.effectAllowed = "move"; @@ -107,7 +84,6 @@ function initTableDragDrop(table) { // Handle drag end row.addEventListener("dragend", function () { - console.log(`Drag ended on row ${row.id}`); row.draggable = false; row.classList.remove("dragged-row"); @@ -132,8 +108,6 @@ function initTableDragDrop(table) { } function updateRowPosition(url, position) { - console.log(`Updating row position: ${url} to position ${position}`); - // Get the CSRF token const csrfToken = document .querySelector("meta[name='csrf-token']") @@ -157,7 +131,6 @@ function updateRowPosition(url, position) { if (!response.ok) { throw new Error(`HTTP error ${response.status}`); } - console.log("Position updated successfully"); }) .catch(function (error) { console.error("Error updating position:", error); diff --git a/lib/active_admin/reorderable/dsl.rb b/lib/active_admin/reorderable/dsl.rb index 70c2bbe..9697d52 100644 --- a/lib/active_admin/reorderable/dsl.rb +++ b/lib/active_admin/reorderable/dsl.rb @@ -5,11 +5,8 @@ module DSL # This method is called on the resource DSL (ActiveAdmin.register) def reorderable # Log that we're registering the reorderable functionality - puts "REGISTERING REORDERABLE FOR #{self.class.name} ###############" - # Add the member action for handling reordering via AJAX member_action :reorder, method: :post do - puts "REORDER ACTION CALLED FOR #{resource.class.name}:#{resource.id} ###############" resource.insert_at(params[:position].to_i) head :ok end @@ -20,17 +17,13 @@ def reorderable ::ActiveAdmin::Views::IndexTableFor.class_eval do def reorder_column column "", data: { column: 'reorder' }, class: "reorder-handle-col", sortable: false do |resource| - puts "RENDERING REORDER HANDLE FOR #{resource.class.name}:#{resource.id} ###############" # Get the URL for the reorder action aa_resource = active_admin_namespace.resource_for(resource.class) url = aa_resource.route_member_action_path(:reorder, resource) - puts "REORDER URL: #{url.inspect} for resource ID #{resource.id.inspect} ###############" # Test both attribute formats - puts "GENERATING SPAN WITH data-reorder-url=#{url.inspect} ###############" - # Render the handle with an SVG icon - ensure we're using valid HTML attributes content_tag :span, class: 'reorder-handle', diff --git a/lib/active_admin/reorderable/table_methods.rb b/lib/active_admin/reorderable/table_methods.rb index 9499c5c..c1378b1 100644 --- a/lib/active_admin/reorderable/table_methods.rb +++ b/lib/active_admin/reorderable/table_methods.rb @@ -3,10 +3,8 @@ module Reorderable module TableMethods def reorder_column - puts "IN REORDER_COLUMN ###############" # Add data attribute to help with debugging column '', class: 'reorder-handle-col', data: { reorderable_handle: true } do |resource| - puts "RENDERING HANDLE FOR RESOURCE #{resource.id} ###############" reorder_handle_for(resource) end end @@ -14,12 +12,9 @@ def reorder_column private def reorder_handle_for(resource) - puts "IN REORDER_HANDLE_FOR #{resource.id} ###############" aa_resource = active_admin_namespace.resource_for(resource.class) url = aa_resource.route_member_action_path(:reorder, resource) - puts "REORDER URL: #{url} ###############" - # Create a handle that works with both classic AA and AA4 with Tailwind span(reorder_handle_content, class: 'reorder-handle', @@ -43,7 +38,6 @@ def reorder_handle_content # Attempt to detect and include in AA4's data table class if it exists if defined?(::ActiveAdmin::Views::IndexAsTable::IndexTableFor) - puts "INCLUDING TABLE METHODS IN IndexAsTable::IndexTableFor ###############" ::ActiveAdmin::Views::IndexAsTable::IndexTableFor.send(:include, TableMethods) end end diff --git a/lib/active_admin/views/index_as_reorderable_table.rb b/lib/active_admin/views/index_as_reorderable_table.rb index 871ab20..73a5d79 100644 --- a/lib/active_admin/views/index_as_reorderable_table.rb +++ b/lib/active_admin/views/index_as_reorderable_table.rb @@ -4,12 +4,10 @@ module Views # In ActiveAdmin 4.0, we're adding the reorder_column method directly to IndexTableFor class IndexAsReorderableTable < IndexAsTable def self.index_name - puts "IN INDEX_NAME ###############" 'reorderable_table' end def build(page_presenter, collection) - puts "IN BUILD ###############" add_class 'aa-reorderable' # Add data-reorderable attribute for easier JS selection with ActiveAdmin 4 @table_options = { data: { reorderable: true } } @@ -17,21 +15,13 @@ def build(page_presenter, collection) end def table_for(*args, &block) - puts "IN TABLE_FOR ###############" - puts "ARGS: #{args.inspect} ###############" - puts "BLOCK GIVEN: #{block_given?} ###############" - # Ensure the first column is a reorder handle new_block = proc do - puts "INSIDE NEW BLOCK ###############" # Try both methods of adding the reorder column if respond_to?(:reorder_column) - puts "CALLING REORDER_COLUMN FROM TABLE_FOR ###############" reorder_column else - puts "ADDING MANUAL REORDER COLUMN ###############" column '', class: 'reorder-handle-col' do |resource| - puts "RENDERING MANUAL HANDLE FOR #{resource.id} ###############" span(' '.html_safe, @@ -49,14 +39,10 @@ def table_for(*args, &block) # First try with our custom table component begin - puts "TRYING TO INSERT REORDERABLE TABLE ###############" tag = insert_tag ReorderableTableFor, *args, &new_block - puts "REORDERABLE TABLE INSERTED: #{tag.class.name} ###############" tag rescue => e # If that fails, try with the standard AA4 table - puts "ERROR WITH REORDERABLE TABLE: #{e.message} ###############" - puts "TRYING WITH STANDARD TABLE ###############" super(*args, &new_block) end end diff --git a/lib/active_admin/views/reorderable_table_for.rb b/lib/active_admin/views/reorderable_table_for.rb index da62f17..32023e5 100644 --- a/lib/active_admin/views/reorderable_table_for.rb +++ b/lib/active_admin/views/reorderable_table_for.rb @@ -4,20 +4,14 @@ class ReorderableTableFor < IndexAsTable::IndexTableFor builder_method :reorderable_table_for def build(collection, options = {}, &block) - puts "IN REORDERABLE_TABLE_FOR BUILD ###############" # Add both classic and Tailwind-compatible classes options[:class] = [options[:class], 'aa-reorderable', 'data-table'].compact.join(' ') # Add data attribute for easier selection with modern JS options[:data] ||= {} options[:data][:reorderable] = true - puts "COLLECTION CLASS: #{collection.class.name} ###############" - puts "OPTIONS: #{options.inspect} ###############" - super(collection, options) do - puts "CALLING REORDER_COLUMN ###############" reorder_column - puts "CALLING BLOCK ###############" block.call if block.present? end end @@ -25,17 +19,12 @@ def build(collection, options = {}, &block) # Try to monkey-patch ActiveAdmin 4.0's table implementation if it exists begin - puts "CHECKING FOR ActiveAdmin 4.0 TABLE CLASSES ###############" aa4_table_classes = ActiveAdmin::Views.constants.select { |c| c.to_s.include?('Table') } - puts "FOUND TABLE CLASSES: #{aa4_table_classes.join(', ')} ###############" if defined?(::ActiveAdmin::Views::Table) - puts "FOUND ActiveAdmin::Views::Table, EXTENDING IT ###############" class ::ActiveAdmin::Views::Table def reorderable_column - puts "AA4 TABLE REORDERABLE_COLUMN CALLED ###############" column '', class: 'reorder-handle-col', data: { reorderable_handle: true } do |resource| - puts "AA4 RENDERING HANDLE FOR RESOURCE #{resource.id} ###############" aa_resource = active_admin_namespace.resource_for(resource.class) url = aa_resource.route_member_action_path(:reorder, resource) @@ -51,8 +40,6 @@ def reorderable_column end end end - rescue => e - puts "ERROR CHECKING FOR AA4 TABLES: #{e.message} ###############" end end end diff --git a/lib/activeadmin_reorderable/engine.rb b/lib/activeadmin_reorderable/engine.rb index ec6f925..2113a44 100644 --- a/lib/activeadmin_reorderable/engine.rb +++ b/lib/activeadmin_reorderable/engine.rb @@ -14,8 +14,6 @@ class Engine < Rails::Engine # Add to importmap for ActiveAdmin 4 app.config.importmap.paths << Engine.root.join("config/importmap.rb") app.config.importmap.cache_sweepers << Engine.root.join("app/assets/javascripts") - - puts "Added activeadmin_reorderable to importmap paths ###############" end initializer "activeadmin_reorderable.load_views", after: "active_admin.load_views" do @@ -33,14 +31,12 @@ class Engine < Rails::Engine # Setup ActiveAdmin importmap integration initializer "activeadmin_reorderable.setup_importmap", after: "activeadmin.importmap" do - puts "Setting up ActiveAdmin importmap for activeadmin_reorderable ###############" # Make sure ActiveAdmin knows about our JavaScript if defined?(ActiveAdmin.importmap) js_path = Engine.root.join("app/assets/javascripts/activeadmin_reorderable.js") if File.exist?(js_path) - puts "Registering activeadmin_reorderable.js with ActiveAdmin importmap ###############" ActiveAdmin.importmap.pin "activeadmin_reorderable", to: "activeadmin_reorderable.js", preload: true else puts "WARNING: Could not find #{js_path} ###############"