diff --git a/app/controllers/results_controller.rb b/app/controllers/results_controller.rb index a5491ed3d..28f61dd6b 100644 --- a/app/controllers/results_controller.rb +++ b/app/controllers/results_controller.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true class ResultsController < ApplicationController + skip_before_action :verify_authenticity_token, only: %i(create update destroy duplicate) before_action :load_my_module - before_action :load_vars, only: %i(destroy elements assets upload_attachment update_view_state update_asset_view_mode update) + before_action :load_vars, only: %i(destroy elements assets upload_attachment + update_view_state update_asset_view_mode update duplicate) before_action :check_destroy_permissions, only: :destroy def index @@ -113,6 +115,16 @@ class ResultsController < ApplicationController redirect_to archive_my_module_path(@my_module) end + def duplicate + ActiveRecord::Base.transaction do + new_result = @result.duplicate( + @my_module, current_user, result_name: "#{@result.name} (1)" + ) + + render json: new_result, serializer: ResultSerializer, user: current_user + end + end + private def result_params diff --git a/app/javascript/vue/results/result.vue b/app/javascript/vue/results/result.vue index 1a6233dc0..b2a8af48e 100644 --- a/app/javascript/vue/results/result.vue +++ b/app/javascript/vue/results/result.vue @@ -349,7 +349,9 @@ }, duplicateResult() { - + axios.post(this.urls.duplicate_url).then((_) => { + this.$emit('duplicated'); + }); }, moveElement(position, target_id) { this.elements.splice(position, 1) @@ -363,8 +365,8 @@ this.$emit('result:move_element', target_id) }, updateName(name) { - axios.patch(this.urls.update_url, { result: { name: name } }, (_) => { - this.$emit('resultUpdated') + axios.patch(this.urls.update_url, { result: { name: name } }).then((_) => { + this.$emit('updated'); }); } } diff --git a/app/javascript/vue/results/results.vue b/app/javascript/vue/results/results.vue index 888b2f84f..65fbab5db 100644 --- a/app/javascript/vue/results/results.vue +++ b/app/javascript/vue/results/results.vue @@ -14,6 +14,7 @@ :resultToReload="resultToReload" @result:elements:loaded="resultToReload = null" @result:move_element="reloadResult" + @duplicated="loadResults" /> diff --git a/app/models/result.rb b/app/models/result.rb index d094d4171..98f7b2558 100644 --- a/app/models/result.rb +++ b/app/models/result.rb @@ -54,6 +54,35 @@ class Result < ApplicationRecord end end + def duplicate(my_module, user, result_name: nil) + ActiveRecord::Base.transaction do + new_result = my_module.results.new( + name: result_name || name, + user: user + ) + new_result.save! + + # Copy texts + result_texts.each do |result_text| + result_text.duplicate(new_result) + end + + # Copy assets + assets.each do |asset| + new_asset = asset.dup + new_asset.save! + new_result.assets << new_asset + end + + # Copy tables + tables.each do |table| + table.duplicate(new_result, user) + end + + new_result + end + end + def default_view_state { 'assets' => { 'sort' => 'new' } } end diff --git a/app/models/result_text.rb b/app/models/result_text.rb index e3b34b249..fe686d900 100644 --- a/app/models/result_text.rb +++ b/app/models/result_text.rb @@ -15,4 +15,22 @@ class ResultText < ApplicationRecord strip_tags(text.truncate(64)) end + + def duplicate(result, position = nil) + ActiveRecord::Base.transaction do + new_result_text = result.result_texts.create!( + text: text + ) + + # Copy results tinyMce assets + clone_tinymce_assets(new_result_text, result.my_module.team) + + result.result_orderable_elements.create!( + position: position || result.result_orderable_elements.length, + orderable: new_result_text + ) + + new_result_text + end + end end diff --git a/app/models/table.rb b/app/models/table.rb index 3c4da0c6a..b6b55be33 100644 --- a/app/models/table.rb +++ b/app/models/table.rb @@ -134,23 +134,44 @@ class Table < ApplicationRecord end end - def duplicate(step, user, position = nil) - ActiveRecord::Base.transaction do - new_table = step.tables.create!( - name: name, - contents: contents.encode('UTF-8', 'UTF-8'), - team: step.protocol.team, - created_by: user, - metadata: metadata, - last_modified_by: user - ) + def duplicate(parent, user, position = nil) + case parent + when Step + ActiveRecord::Base.transaction do + new_table = parent.tables.create!( + name: name, + contents: contents.encode('UTF-8', 'UTF-8'), + team: parent.protocol.team, + created_by: user, + metadata: metadata, + last_modified_by: user + ) - step.step_orderable_elements.create!( - position: position || step.step_orderable_elements.length, - orderable: new_table.step_table - ) + parent.step_orderable_elements.create!( + position: position || parent.step_orderable_elements.length, + orderable: new_table.step_table + ) - new_table + new_table + end + when Result + ActiveRecord::Base.transaction do + new_table = parent.tables.create!( + name: name, + contents: contents.encode('UTF-8', 'UTF-8'), + team: parent.my_module.team, + created_by: user, + metadata: metadata, + last_modified_by: user + ) + + parent.result_orderable_elements.create!( + position: parent.result_orderable_elements.length, + orderable: new_table.result_table + ) + + new_table + end end end end diff --git a/app/serializers/result_serializer.rb b/app/serializers/result_serializer.rb index 3fd2527a4..dd8010d04 100644 --- a/app/serializers/result_serializer.rb +++ b/app/serializers/result_serializer.rb @@ -83,6 +83,10 @@ class ResultSerializer < ActiveModel::Serializer }) end + if can_create_results?(object.my_module) + urls_list[:duplicate_url] = duplicate_my_module_result_url(object.my_module, object) + end + urls_list end end diff --git a/config/routes.rb b/config/routes.rb index cd54a17f0..05179fcc6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -538,6 +538,7 @@ Rails.application.routes.draw do post :upload_attachment post :update_view_state post :update_asset_view_mode + post :duplicate end resources :tables, controller: 'result_elements/tables', only: %i(create destroy update) do