mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-15 05:34:53 +08:00
Clone file version history when making new protocol draft [SCI-11230]
This commit is contained in:
parent
89bc4102ee
commit
d3292f6c4a
3 changed files with 49 additions and 35 deletions
|
@ -146,49 +146,61 @@ class Asset < ApplicationRecord
|
|||
file&.blob&.content_type
|
||||
end
|
||||
|
||||
def duplicate(new_name: nil)
|
||||
def duplicate(new_name: nil, include_file_versions: false)
|
||||
new_asset = dup
|
||||
file.filename = new_name if new_name
|
||||
|
||||
return unless new_asset.save
|
||||
|
||||
duplicate_file(new_asset, new_name: new_name)
|
||||
duplicate_file(new_asset, new_name: new_name, include_file_versions: include_file_versions)
|
||||
|
||||
new_asset
|
||||
end
|
||||
|
||||
def duplicate_file(to_asset, new_name: nil)
|
||||
def duplicate_blob(blob, attach_method, metadata: nil)
|
||||
new_blob = nil
|
||||
|
||||
blob.open do |tmp_file|
|
||||
new_blob = ActiveStorage::Blob.create_and_upload!(
|
||||
io: tmp_file,
|
||||
filename: blob.filename,
|
||||
metadata: metadata || blob.metadata
|
||||
)
|
||||
|
||||
attach_method.call(new_blob)
|
||||
end
|
||||
|
||||
new_blob
|
||||
end
|
||||
|
||||
def duplicate_file_versions(to_asset)
|
||||
previous_files.map(&:blob).sort_by(&:created_at).each do |blob|
|
||||
duplicate_blob(blob, to_asset.previous_files.method(:attach)) # .update_column(:created_at, blob.created_at)
|
||||
end
|
||||
end
|
||||
|
||||
def duplicate_file(to_asset, new_name: nil, include_file_versions: false)
|
||||
return unless file.attached?
|
||||
|
||||
raise ArgumentError, 'Destination asset should be persisted first!' unless to_asset.persisted?
|
||||
|
||||
file.blob.open do |tmp_file|
|
||||
metadata = blob.metadata.dup
|
||||
metadata = file.blob.metadata.dup
|
||||
|
||||
# set new name in metadata for OVE and MarvinJS files
|
||||
if new_name && file.blob.metadata['asset_type'].in?(%w(gene_sequence marvinjs))
|
||||
new_metadata_name = File.basename(new_name, File.extname(new_name))
|
||||
metadata['name'] = new_metadata_name
|
||||
end
|
||||
|
||||
to_blob = ActiveStorage::Blob.create_and_upload!(
|
||||
io: tmp_file,
|
||||
filename: blob.filename,
|
||||
metadata: metadata
|
||||
)
|
||||
to_asset.attach_file_version(to_blob)
|
||||
# set new name in metadata for OVE and MarvinJS files
|
||||
if new_name && file.blob.metadata['asset_type'].in?(%w(gene_sequence marvinjs))
|
||||
new_metadata_name = File.basename(new_name, File.extname(new_name))
|
||||
metadata['name'] = new_metadata_name
|
||||
end
|
||||
|
||||
if preview_image.attached?
|
||||
preview_image.blob.open do |tmp_preview_image|
|
||||
to_blob = ActiveStorage::Blob.create_and_upload!(
|
||||
io: tmp_preview_image,
|
||||
filename: blob.filename,
|
||||
metadata: blob.metadata
|
||||
)
|
||||
to_asset.attach_preview_image_version(to_blob)
|
||||
end
|
||||
unless include_file_versions
|
||||
metadata.delete('version')
|
||||
metadata.delete('restored_from_version')
|
||||
end
|
||||
|
||||
duplicate_file_versions(to_asset) if include_file_versions
|
||||
duplicate_blob(blob, to_asset.method(:attach_file_version), metadata: metadata)
|
||||
duplicate_blob(preview_image.blob, to_asset.method(:attach_preview_image_version)) if preview_image.attached?
|
||||
|
||||
to_asset.post_process_file
|
||||
end
|
||||
|
||||
|
|
|
@ -351,7 +351,9 @@ class Protocol < ApplicationRecord
|
|||
end
|
||||
|
||||
# Deep-clone given array of assets
|
||||
def self.deep_clone_assets(assets_to_clone)
|
||||
# There is an issue with Delayed Job delayed methods, ruby 3, and keyword arguments (https://github.com/collectiveidea/delayed_job/issues/1134)
|
||||
# so we're forced to use a normal argument with default value.
|
||||
def self.deep_clone_assets(assets_to_clone, include_file_versions = false)
|
||||
ActiveRecord::Base.no_touching do
|
||||
assets_to_clone.each do |src_id, dest_id|
|
||||
src = Asset.find_by(id: src_id)
|
||||
|
@ -360,12 +362,12 @@ class Protocol < ApplicationRecord
|
|||
next unless src.present? && dest.present?
|
||||
|
||||
# Clone file
|
||||
src.duplicate_file(dest)
|
||||
src.duplicate_file(dest, include_file_versions: include_file_versions)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.clone_contents(src, dest, current_user, clone_keywords, only_contents = false)
|
||||
def self.clone_contents(src, dest, current_user, clone_keywords, only_contents: false, include_file_versions: false)
|
||||
dest.update(description: src.description, name: src.name) unless only_contents
|
||||
|
||||
src.clone_tinymce_assets(dest, dest.team)
|
||||
|
@ -382,7 +384,7 @@ class Protocol < ApplicationRecord
|
|||
|
||||
# Copy steps
|
||||
src.steps.each do |step|
|
||||
step.duplicate(dest, current_user, step_position: step.position)
|
||||
step.duplicate(dest, current_user, step_position: step.position, include_file_versions: include_file_versions)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -615,7 +617,7 @@ class Protocol < ApplicationRecord
|
|||
return draft if draft.invalid?
|
||||
|
||||
ActiveRecord::Base.no_touching do
|
||||
draft = deep_clone(draft, current_user)
|
||||
draft = deep_clone(draft, current_user, include_file_versions: true)
|
||||
end
|
||||
|
||||
parent_protocol.user_assignments.each do |parent_user_assignment|
|
||||
|
@ -760,7 +762,7 @@ class Protocol < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def deep_clone(clone, current_user)
|
||||
def deep_clone(clone, current_user, include_file_versions: false)
|
||||
# Save cloned protocol first
|
||||
success = clone.save
|
||||
|
||||
|
@ -772,7 +774,7 @@ class Protocol < ApplicationRecord
|
|||
|
||||
raise ActiveRecord::RecordNotSaved unless success
|
||||
|
||||
Protocol.clone_contents(self, clone, current_user, true, true)
|
||||
Protocol.clone_contents(self, clone, current_user, true, only_contents: true, include_file_versions: include_file_versions)
|
||||
|
||||
clone.reload
|
||||
clone
|
||||
|
|
|
@ -117,7 +117,7 @@ class Step < ApplicationRecord
|
|||
step_texts.order(created_at: :asc).first
|
||||
end
|
||||
|
||||
def duplicate(protocol, user, step_position: nil, step_name: nil)
|
||||
def duplicate(protocol, user, step_position: nil, step_name: nil, include_file_versions: false)
|
||||
ActiveRecord::Base.transaction do
|
||||
assets_to_clone = []
|
||||
|
||||
|
@ -153,7 +153,7 @@ class Step < ApplicationRecord
|
|||
end
|
||||
|
||||
# Call clone helper
|
||||
Protocol.delay(queue: :assets).deep_clone_assets(assets_to_clone)
|
||||
Protocol.delay(queue: :assets).deep_clone_assets(assets_to_clone, include_file_versions)
|
||||
|
||||
new_step
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue