mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-11 23:54:43 +08:00
Add duplication to components [SCI-7108]
This commit is contained in:
parent
3802355964
commit
1bac9aeb4c
15 changed files with 157 additions and 53 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue