From 56744e2dcd8e71d95999460e810dffb7efe91131 Mon Sep 17 00:00:00 2001
From: Ivan Kljun <ivan@scinote.net>
Date: Tue, 5 Sep 2023 11:02:39 +0200
Subject: [PATCH] Use act_as_list for reordering result elements, localize
 title for result reordering modal [SCI-9182]

---
 .../result_orderable_elements_controller.rb    | 18 ++++++++++--------
 app/javascript/vue/results/result.vue          |  2 +-
 app/models/result_orderable_element.rb         |  1 +
 app/serializers/result_serializer.rb           |  3 ++-
 config/locales/en.yml                          |  2 ++
 config/routes.rb                               |  3 +++
 6 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/app/controllers/result_orderable_elements_controller.rb b/app/controllers/result_orderable_elements_controller.rb
index d2cd71e83..7f516f7b0 100644
--- a/app/controllers/result_orderable_elements_controller.rb
+++ b/app/controllers/result_orderable_elements_controller.rb
@@ -5,17 +5,19 @@ class ResultOrderableElementsController < ApplicationController
   before_action :check_manage_permissions
 
   def reorder
-    @result.with_lock do
-      params[:result_orderable_element_positions].each do |id, position|
-        @result.result_orderable_elements.find(id).update_column(:position, position)
+    params[:result_orderable_element_positions].each do |id, position|
+      result_element = @result.result_orderable_elements.find(id)
+      ActiveRecord::Base.transaction do
+        result_element.insert_at(position)
       end
-
-      log_activity(:result_content_rearranged, @my_module.experiment.project, my_module: @my_module.id)
-
-      @result.touch
     end
 
+    log_activity(:result_content_rearranged, @my_module.experiment.project, my_module: @my_module.id)
+    @result.touch
+
     render json: params[:result_orderable_element_positions], status: :ok
+  rescue ActiveRecord::RecordInvalid
+    render json: { errors: result_element.errors }, status: :conflict
   end
 
   private
@@ -39,7 +41,7 @@ class ResultOrderableElementsController < ApplicationController
       .call(activity_type: type_of,
             owner: current_user,
             subject: @result,
-            team: @@my_module.team,
+            team: @my_module.team,
             project: project,
             message_items: message_items)
   end
diff --git a/app/javascript/vue/results/result.vue b/app/javascript/vue/results/result.vue
index 70f25688f..55b8794a5 100644
--- a/app/javascript/vue/results/result.vue
+++ b/app/javascript/vue/results/result.vue
@@ -106,7 +106,7 @@
     </div>
 
     <ReorderableItemsModal v-if="reordering"
-      title="Placeholder title for this modal"
+      :title="i18n.t('my_modules.modals.reorder_results.title')"
       :items="reorderableElements"
       @reorder="updateElementOrder"
       @close="closeReorderModal"
diff --git a/app/models/result_orderable_element.rb b/app/models/result_orderable_element.rb
index 5ba91b4d7..eb43e280c 100644
--- a/app/models/result_orderable_element.rb
+++ b/app/models/result_orderable_element.rb
@@ -8,6 +8,7 @@ class ResultOrderableElement < ApplicationRecord
 
   belongs_to :result, inverse_of: :result_orderable_elements, touch: true
   belongs_to :orderable, polymorphic: true, inverse_of: :result_orderable_element
+  acts_as_list scope: :result, top_of_list: 0, sequential_updates: true
 
   private
 
diff --git a/app/serializers/result_serializer.rb b/app/serializers/result_serializer.rb
index 0c3e04433..b267933f7 100644
--- a/app/serializers/result_serializer.rb
+++ b/app/serializers/result_serializer.rb
@@ -79,7 +79,8 @@ class ResultSerializer < ActiveModel::Serializer
         update_asset_view_mode_url: update_asset_view_mode_my_module_result_path(object.my_module, object),
         update_view_state_url: update_view_state_my_module_result_path(object.my_module, object),
         direct_upload_url: rails_direct_uploads_url,
-        upload_attachment_url: upload_attachment_my_module_result_path(object.my_module, object)
+        upload_attachment_url: upload_attachment_my_module_result_path(object.my_module, object),
+        reorder_elements_url: reorder_result_result_orderable_elements_path(result_id: object.id)
       })
     end
 
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 874210977..eb5912a98 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1387,6 +1387,8 @@ en:
       snapshot_error:
         title: "Snapshot error"
         body_html: "<strong>%{repository}</strong> inventory snapshot failed to generate. Please contact support if this problem persists."
+      reorder_results:
+        title: "Rearrange result content"
     modules_list_partial:
       private_tasks_html: 'Assigned to <strong>%{nr}</strong> private task(s)'
       no_results:
diff --git a/config/routes.rb b/config/routes.rb
index 05179fcc6..f91b50026 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -614,6 +614,9 @@ Rails.application.routes.draw do
     end
 
     resources :results, only: [:update, :destroy] do
+      resources :result_orderable_elements do
+        post :reorder, on: :collection
+      end
       resources :result_comments,
                 path: '/comments',
                 only: %i(create index update destroy)