Add step duplication [SCI-7109]

This commit is contained in:
Anton 2022-08-23 17:54:33 +02:00
parent 1bac9aeb4c
commit bc112dd6af
8 changed files with 69 additions and 36 deletions

View file

@ -5,7 +5,8 @@ class StepsController < ApplicationController
include MarvinJsActions
before_action :load_vars, only: %i(edit update destroy show toggle_step_state checklistitem_state update_view_state
move_up move_down update_asset_view_mode elements attachments upload_attachment)
move_up move_down update_asset_view_mode elements
attachments upload_attachment duplicate)
before_action :load_vars_nested, only: %i(new create index reorder)
before_action :convert_table_contents_to_utf8, only: %i(create update)
@ -231,6 +232,19 @@ class StepsController < ApplicationController
end
end
def duplicate
ActiveRecord::Base.transaction do
position = @step.position
@protocol.steps.where('position > ?', position).order(position: :desc).each do |step|
step.update(position: step.position + 1)
end
new_step = @step.duplicate(@protocol, current_user, position + 1)
render json: new_step, serializer: StepSerializer, user: current_user
end
rescue ActiveRecord::RecordInvalid
head :unprocessable_entity
end
def update_old
respond_to do |format|
old_description = @step.description

View file

@ -104,6 +104,7 @@
@step:delete="updateStepsPosition"
@step:update="updateStep"
@stepUpdated="refreshProtocolStatus"
@step:insert="updateStepsPosition"
:reorderStepUrl="steps.length > 1 ? urls.reorder_steps_url : null"
/>
</div>

View file

@ -113,6 +113,10 @@
<i class="fas fas-rotated-90 fa-exchange-alt"></i>
{{ i18n.t('protocols.steps.options_dropdown.rearrange') }}
</li>
<li v-if="urls.duplicate_step_url" class="action" @click="duplicateStep">
<i class="fas fa-clone"></i>
{{ i18n.t('protocols.steps.options_dropdown.duplicate') }}
</li>
<li v-if="urls.delete_url" class="action" @click="showDeleteModal">
<i class="fas fa-trash"></i>
{{ i18n.t('protocols.steps.options_dropdown.delete') }}
@ -452,6 +456,11 @@
})
elements.push(element);
this.reorderElements(elements);
},
duplicateStep() {
$.post(this.urls.duplicate_step_url, (result) => {
this.$emit('step:insert', result.data);
});
}
}
}

View file

@ -254,7 +254,6 @@ class Protocol < ApplicationRecord
end
def self.clone_contents(src, dest, current_user, clone_keywords, only_contents = false)
assets_to_clone = []
dest.update(description: src.description, name: src.name) unless only_contents
src.clone_tinymce_assets(dest, dest.team)
@ -271,40 +270,8 @@ class Protocol < ApplicationRecord
# Copy steps
src.steps.each do |step|
step2 = Step.new(
name: step.name,
position: step.position,
completed: false,
user: current_user,
protocol: dest
)
step2.save!
# Copy texts
step.step_texts.each do |step_text|
step_text.duplicate(step2, step_text.step_orderable_element.position)
end
# Copy checklists
step.checklists.asc.each do |checklist|
checklist.duplicate(step2, current_user, checklist.step_orderable_element.position)
end
# "Shallow" Copy assets
step.assets.each do |asset|
asset2 = asset.dup
asset2.save!
step2.assets << asset2
assets_to_clone << [asset.id, asset2.id]
end
# Copy tables
step.tables.each do |table|
table.duplicate(step2, current_user, table.step_table.step_orderable_element.position)
end
step.duplicate(dest, current_user, step.position)
end
# Call clone helper
Protocol.delay(queue: :assets).deep_clone_assets(assets_to_clone)
end
def in_repository_active?

View file

@ -151,6 +151,45 @@ class Step < ApplicationRecord
step_texts.order(created_at: :asc).first
end
def duplicate(protocol, user, step_position = 0)
assets_to_clone = []
new_step = protocol.steps.new(
name: name,
position: step_position || protocol.steps.length,
completed: false,
user: user
)
new_step.save!
# Copy texts
step_texts.each do |step_text|
step_text.duplicate(new_step, step_text.step_orderable_element.position)
end
# Copy checklists
checklists.asc.each do |checklist|
checklist.duplicate(new_step, user, checklist.step_orderable_element.position)
end
# "Shallow" Copy assets
assets.each do |asset|
new_asset = asset.dup
new_asset.save!
new_step.assets << new_asset
assets_to_clone << [asset.id, new_asset.id]
end
# Copy tables
tables.each do |table|
table.duplicate(new_step, user, table.step_table.step_orderable_element.position)
end
# Call clone helper
Protocol.delay(queue: :assets).deep_clone_assets(assets_to_clone)
new_step
end
private
def move_in_protocol(direction)

View file

@ -89,7 +89,8 @@ class StepSerializer < ActiveModel::Serializer
update_view_state_step_url: update_view_state_step_path(object),
direct_upload_url: rails_direct_uploads_url,
upload_attachment_url: upload_attachment_step_path(object),
reorder_elements_url: reorder_step_step_orderable_elements_path(step_id: object.id)
reorder_elements_url: reorder_step_step_orderable_elements_path(step_id: object.id),
duplicate_step_url: duplicate_step_path(object)
})
end

View file

@ -2558,6 +2558,7 @@ en:
options_dropdown:
title: 'Step options'
rearrange: 'Rearrange content'
duplicate: 'Duplicate'
delete: 'Delete'
insert:
button: 'Insert'

View file

@ -482,6 +482,7 @@ Rails.application.routes.draw do
put 'move_up'
post 'update_view_state'
post 'update_asset_view_mode'
post 'duplicate'
end
end