Add duplication to components [SCI-7108]

This commit is contained in:
Anton 2022-08-22 14:02:19 +02:00
parent 3802355964
commit 1bac9aeb4c
15 changed files with 157 additions and 53 deletions

View file

@ -2,7 +2,7 @@
module StepElements
class ChecklistsController < BaseController
before_action :load_checklist, only: %i(update destroy)
before_action :load_checklist, only: %i(update destroy duplicate)
def create
checklist = @step.checklists.build(
@ -37,6 +37,19 @@ module StepElements
end
end
def duplicate
ActiveRecord::Base.transaction do
position = @checklist.step_orderable_element.position
@step.step_orderable_elements.where('position > ?', position).order(position: :desc).each do |element|
element.update(position: element.position + 1)
end
new_checklist = @checklist.duplicate(@step, current_user, position + 1)
render_step_orderable_element(new_checklist)
end
rescue ActiveRecord::RecordInvalid
head :unprocessable_entity
end
private
def checklist_params

View file

@ -2,7 +2,7 @@
module StepElements
class TablesController < BaseController
before_action :load_table, only: %i(update destroy)
before_action :load_table, only: %i(update destroy duplicate)
def create
step_table = @step.step_tables.new(table:
@ -42,6 +42,21 @@ module StepElements
end
end
def duplicate
ActiveRecord::Base.transaction do
position = @table.step_table.step_orderable_element.position
@step.step_orderable_elements.where('position > ?', position).order(position: :desc).each do |element|
element.update(position: element.position + 1)
end
new_table = @table.duplicate(@step, current_user, position + 1)
render_step_orderable_element(new_table.step_table)
end
rescue ActiveRecord::RecordInvalid
head :unprocessable_entity
end
private
def table_params
params.permit(:name, :contents)
end

View file

@ -2,7 +2,7 @@
module StepElements
class TextsController < BaseController
before_action :load_step_text, only: %i(update destroy)
before_action :load_step_text, only: %i(update destroy duplicate)
def create
step_text = @step.step_texts.build
@ -38,6 +38,19 @@ module StepElements
end
end
def duplicate
ActiveRecord::Base.transaction do
position = @step_text.step_orderable_element.position
@step.step_orderable_elements.where('position > ?', position).order(position: :desc).each do |element|
element.update(position: element.position + 1)
end
new_step_text = @step_text.duplicate(@step, position + 1)
render_step_orderable_element(new_step_text)
end
rescue ActiveRecord::RecordInvalid
head :unprocessable_entity
end
private
def step_text_params

View file

@ -135,6 +135,7 @@
@component:delete="deleteElement"
@update="updateElement"
@reorder="openReorderModal"
@component:insert="insertElement"
/>
</template>
<Attachments v-if="attachments.length"
@ -440,6 +441,17 @@
copyPasteImageModal(pasteImages) {
this.pasteImages = pasteImages;
this.showClipboardPasteModal = true;
},
insertElement(element) {
let position = element.attributes.position;
let elements = this.elements.map( s => {
if (s.attributes.position >= position) {
s.attributes.position += 1;
}
return s;
})
elements.push(element);
this.reorderElements(elements);
}
}
}

View file

@ -25,6 +25,9 @@
<button v-if="element.attributes.orderable.urls.update_url" class="btn icon-btn btn-light" @click="editingName = true" tabindex="-1">
<i class="fas fa-pen"></i>
</button>
<button v-if="element.attributes.orderable.urls.duplicate_url" class="btn icon-btn btn-light" tabindex="-1" @click="duplicateElement">
<i class="fas fa-clone"></i>
</button>
<button v-if="element.attributes.orderable.urls.delete_url" class="btn icon-btn btn-light" @click="showDeleteModal" tabindex="-1">
<i class="fas fa-trash"></i>
</button>
@ -264,6 +267,11 @@
};
synchronousPost(0);
},
duplicateElement() {
$.post(this.element.attributes.orderable.urls.duplicate_url, (result) => {
this.$emit('component:insert', result.data);
});
}
}
}

View file

@ -22,6 +22,9 @@
<button v-if="element.attributes.orderable.urls.update_url" class="btn icon-btn btn-light" @click="enableNameEdit" tabindex="-1">
<i class="fas fa-pen"></i>
</button>
<button v-if="element.attributes.orderable.urls.duplicate_url" class="btn icon-btn btn-light" tabindex="-1" @click="duplicateElement">
<i class="fas fa-clone"></i>
</button>
<button v-if="element.attributes.orderable.urls.delete_url" class="btn icon-btn btn-light" @click="showDeleteModal" tabindex="-1">
<i class="fas fa-trash"></i>
</button>
@ -171,6 +174,11 @@
readOnly: !this.editingTable,
afterUnlisten: () => setTimeout(this.updateTable, 100) // delay makes cancel button work
});
},
duplicateElement() {
$.post(this.element.attributes.orderable.urls.duplicate_url, (result) => {
this.$emit('component:insert', result.data);
});
}
}
}

View file

@ -8,6 +8,9 @@
<button v-if="element.attributes.orderable.urls.update_url" class="btn icon-btn btn-light" tabindex="-1" @click="enableEditMode($event)">
<i class="fas fa-pen"></i>
</button>
<button v-if="element.attributes.orderable.urls.duplicate_url" class="btn icon-btn btn-light" tabindex="-1" @click="duplicateElement">
<i class="fas fa-clone"></i>
</button>
<button v-if="element.attributes.orderable.urls.delete_url" class="btn icon-btn btn-light" @click="showDeleteModal" tabindex="-1">
<i class="fas fa-trash"></i>
</button>
@ -87,6 +90,11 @@
this.element.attributes.orderable.name = data.data.attributes.name
this.element.attributes.orderable.updated_at = data.data.attributes.updated_at
this.$emit('update', this.element, true)
},
duplicateElement() {
$.post(this.element.attributes.orderable.urls.duplicate_url, (result) => {
this.$emit('component:insert', result.data);
});
}
}
}

View file

@ -52,4 +52,29 @@ class Checklist < ApplicationRecord
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end
def duplicate(step, user, position = nil)
new_checklist = step.checklists.create!(
name: name,
created_by: user,
last_modified_by: user
)
checklist_items.each do |item|
new_checklist.checklist_items.create!(
text: item.text,
checked: false,
position: item.position,
created_by: user,
last_modified_by: user
)
end
step.step_orderable_elements.create!(
position: position || step.step_orderable_elements.length,
orderable: new_checklist
)
new_checklist
end
end

View file

@ -282,45 +282,12 @@ class Protocol < ApplicationRecord
# Copy texts
step.step_texts.each do |step_text|
step_text2 = StepText.new(
text: step_text.text,
step: step2
)
step_text2.save!
# Copy steps tinyMce assets
step_text.clone_tinymce_assets(step_text2, dest.team)
step2.step_orderable_elements.create!(
position: step_text.step_orderable_element.position,
orderable: step_text2
)
step_text.duplicate(step2, step_text.step_orderable_element.position)
end
# Copy checklists
step.checklists.asc.each do |checklist|
checklist2 = Checklist.create!(
name: checklist.name,
step: step2,
created_by: current_user,
last_modified_by: current_user
)
checklist.checklist_items.each do |item|
ChecklistItem.create!(
text: item.text,
checked: false,
checklist: checklist2,
position: item.position,
created_by: current_user,
last_modified_by: current_user
)
end
step2.step_orderable_elements.create!(
position: checklist.step_orderable_element.position,
orderable: checklist2
)
checklist.duplicate(step2, current_user, checklist.step_orderable_element.position)
end
# "Shallow" Copy assets
@ -333,19 +300,7 @@ class Protocol < ApplicationRecord
# Copy tables
step.tables.each do |table|
table2 = Table.create!(
name: table.name,
step: step2,
contents: table.contents.encode('UTF-8', 'UTF-8'),
team: dest.team,
created_by: current_user,
last_modified_by: current_user
)
step2.step_orderable_elements.create!(
position: table.step_table.step_orderable_element.position,
orderable: table2.step_table
)
table.duplicate(step2, current_user, table.step_table.step_orderable_element.position)
end
end
# Call clone helper

View file

@ -17,4 +17,20 @@ class StepText < ApplicationRecord
strip_tags(text.truncate(64))
end
def duplicate(step, position = nil)
new_step_text = step.step_texts.create!(
text: text
)
# Copy steps tinyMce assets
clone_tinymce_assets(new_step_text, step.protocol.team)
step.step_orderable_elements.create!(
position: position || step.step_orderable_elements.length,
orderable: new_step_text
)
new_step_text
end
end

View file

@ -129,4 +129,21 @@ class Table < ApplicationRecord
end
end
end
def duplicate(step, user, position = nil)
new_table = step.tables.create!(
name: name,
contents: contents.encode('UTF-8', 'UTF-8'),
team: step.protocol.team,
created_by: user,
last_modified_by: user
)
step.step_orderable_elements.create!(
position: position || step.step_orderable_elements.length,
orderable: new_table.step_table
)
new_table
end
end

View file

@ -30,6 +30,7 @@ class ChecklistSerializer < ActiveModel::Serializer
return {} if object.destroyed? || !can_manage_step?(scope[:user] || @instance_options[:user], object.step)
{
duplicate_url: duplicate_step_checklist_path(object.step, object),
delete_url: step_checklist_path(object.step, object),
update_url: step_checklist_path(object.step, object),
reorder_url: reorder_step_checklist_checklist_items_path(object.step, object),

View file

@ -36,6 +36,7 @@ class StepTextSerializer < ActiveModel::Serializer
return {} if object.destroyed? || !can_manage_step?(scope[:user] || @instance_options[:user], object.step)
{
duplicate_url: duplicate_step_text_path(object.step, object),
delete_url: step_text_path(object.step, object),
update_url: step_text_path(object.step, object)
}

View file

@ -22,6 +22,7 @@ class TableSerializer < ActiveModel::Serializer
return {} unless can_manage_step?(scope[:user] || @instance_options[:user], object.step)
{
duplicate_url: duplicate_step_table_path(object.step, object),
delete_url: step_table_path(object.step, object),
update_url: step_table_path(object.step, object)
}

View file

@ -453,9 +453,20 @@ Rails.application.routes.draw do
resources :step_comments,
path: '/comments',
only: %i(create index update destroy)
resources :tables, controller: 'step_elements/tables', only: %i(create destroy update)
resources :texts, controller: 'step_elements/texts', only: %i(create destroy update)
resources :tables, controller: 'step_elements/tables', only: %i(create destroy update) do
member do
post :duplicate
end
end
resources :texts, controller: 'step_elements/texts', only: %i(create destroy update) do
member do
post :duplicate
end
end
resources :checklists, controller: 'step_elements/checklists', only: %i(create destroy update) do
member do
post :duplicate
end
resources :checklist_items, controller: 'step_elements/checklist_items', only: %i(create update destroy) do
patch :toggle, on: :member
post :reorder, on: :collection