-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Richard/eco 63 #346
base: v6
Are you sure you want to change the base?
Richard/eco 63 #346
Changes from 4 commits
b9e1a5c
4f1b7d2
a3d4c11
dcc77c2
6189a82
caa3b50
ecaf31d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,11 @@ def default_actions | |
icon: :edit_box, | ||
url: -> (record) { through_aware_console_url_for(record, action: :edit, safe: true) }, | ||
}, | ||
clone: { | ||
name: :clone, | ||
icon: :plus_circle_multiple_outline, | ||
url: -> (record) { through_aware_console_url_for(record, action: :clone, safe: true) }, | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. jeste prosim upravme patricne cancancan, aby se pocitalo s |
||
show: { | ||
name: :show, | ||
icon: :eye, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,15 @@ def index | |
end | ||
end | ||
|
||
def clone | ||
page = Folio::Page.find(params[:id]) | ||
@page = page.create_clone | ||
@page.title = t("folio.console.clone.cloned_title", | ||
original_title: page.title, | ||
date: Date.today.strftime("%d. %m. %Y")) | ||
render :new | ||
end | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prosim do |
||
private | ||
def index_filters | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
# frozen_string_literal: true | ||
|
||
module Folio::Console::Clonable | ||
extend ActiveSupport::Concern | ||
|
||
DEFAULT_RESET_ATTRIBUTES = [:published_at, :published] | ||
|
||
included do | ||
class_attribute :reference_associations, :duplicated_associations, :reset_attributes, | ||
default: [], instance_writer: false | ||
|
||
self.reset_attributes = DEFAULT_RESET_ATTRIBUTES | ||
end | ||
|
||
class_methods do | ||
def references_original(*associations) | ||
validate_associations!(associations) | ||
self.reference_associations = associations | ||
end | ||
|
||
def duplicates_with_relations(*associations) | ||
validate_associations!(associations) | ||
self.duplicated_associations = associations | ||
end | ||
|
||
def reset_attributes_on_clone(*attributes) | ||
validate_attributes!(attributes) | ||
self.reset_attributes = DEFAULT_RESET_ATTRIBUTES + attributes | ||
end | ||
|
||
private | ||
def validate_associations!(associations) | ||
associations.each do |assoc| | ||
unless reflect_on_association(assoc) | ||
raise ArgumentError, I18n.t("activerecord.errors.clonable.association_not_found", | ||
association: assoc, | ||
model: self.name) | ||
end | ||
end | ||
end | ||
|
||
def validate_attributes!(attributes) | ||
attributes.each do |attr| | ||
unless column_names.include?(attr.to_s) | ||
raise ArgumentError, I18n.t("activerecord.errors.clonable.attribute_not_found", | ||
attribute: attr, | ||
model: self.name) | ||
end | ||
end | ||
end | ||
end | ||
|
||
def create_clone | ||
log("CLONING", :info) | ||
log(I18n.t("cloning.start", model: self.class.name, id: id)) | ||
|
||
clone = deep_dup | ||
log(I18n.t("cloning.deep_dup_finished")) | ||
|
||
copy_references(clone) | ||
log(I18n.t("cloning.references_copied", references: self.class.reference_associations)) | ||
|
||
duplicate_nested_records(clone) | ||
log(I18n.t("cloning.associations_duplicated", associations: self.class.duplicated_associations)) | ||
|
||
reset_clone_attributes(clone) | ||
log(I18n.t("cloning.finished")) | ||
clone | ||
rescue => e | ||
log(I18n.t("cloning.error", message: e.message), :error) | ||
log(e.backtrace.first(5).join("\n"), :error) | ||
raise | ||
end | ||
|
||
private | ||
def reset_clone_attributes(clone) | ||
self.class.reset_attributes.each do |attr| | ||
clone[attr] = nil if clone.has_attribute?(attr) | ||
end | ||
end | ||
|
||
def copy_references(cloned) | ||
return unless self.class.reference_associations.present? | ||
|
||
self.class.reference_associations.each do |assoc| | ||
cloned.public_send("#{assoc}=", public_send(assoc)) | ||
end | ||
end | ||
|
||
def duplicate_nested_records(cloned) | ||
return unless self.class.duplicated_associations.present? | ||
|
||
self.class.duplicated_associations.each do |assoc| | ||
cloned.public_send("#{assoc}=", clone_associated_records(assoc)) | ||
end | ||
end | ||
|
||
def clone_associated_records(association) | ||
originals = public_send(association) | ||
originals = [originals] unless originals.is_a?(ActiveRecord::Relation) | ||
|
||
clones = originals.map do |orig| | ||
clone = orig.deep_dup | ||
|
||
if orig.class.reflect_on_all_associations.present? | ||
orig.class.reflect_on_all_associations.each do |association| | ||
clone_association(orig, clone, association) | ||
end | ||
end | ||
|
||
clone | ||
end | ||
|
||
originals.is_a?(ActiveRecord::Relation) ? clones : clones.first | ||
end | ||
|
||
def clone_association(original, clone, association) | ||
if association.macro == :has_many | ||
clone_has_many_association(original, clone, association) | ||
else | ||
clone_single_association(original, clone, association) | ||
end | ||
end | ||
|
||
def clone_has_many_association(original, clone, association) | ||
return if [:files, :placements].include?(association.name) | ||
associated_records = original.public_send(association.name) | ||
associated_records = associated_records.map { |r| r.deep_dup } unless self.class.reference_associations.include?(association.name) | ||
clone.association(association.name).build(associated_records.map(&:attributes)) | ||
end | ||
|
||
def clone_single_association(original, clone, association) | ||
associated_record = original.public_send(association.name) | ||
return unless associated_record | ||
|
||
associated_record_dup = self.class.reference_associations.include?(association.name) ? | ||
associated_record : | ||
associated_record.deep_dup | ||
|
||
clone.public_send("#{association.name}=", associated_record_dup) | ||
end | ||
|
||
def log(message, level = :info) | ||
if Rails.env.development? && Rails.logger | ||
Rails.logger.tagged("CLONING") do | ||
Rails.logger.public_send(level, message) | ||
end | ||
else | ||
puts "[CLONING] #{message}" | ||
end | ||
end | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moc se mi nelibi, ze je to cele jako concern na model. Pridava to strasne moc metod vcetne Predstovoval bych si to jako concern, ktery prida neco jako Zaroven by to melo fungovat vice magicky a pro vsechny zaznamy (dejme to na |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
= index_header | ||
|
||
= catalogue(@catalogue_model || @pages, @catalogue_options || {}) | ||
ruby: | ||
edit_link :title | ||
|
||
type | ||
|
||
locale_flag if Rails.application.config.folio_pages_locales | ||
|
||
published_toggle | ||
|
||
date(:published_at) | ||
|
||
position_controls if model && model[:ancestry] | ||
|
||
locale = (Folio::Current.site.locales.size > 1 || Rails.application.config.folio_console_add_locale_to_preview_links) ? I18n.locale : nil | ||
|
||
if record.is_a?(Folio::Page) && record.class.try(:public?) | ||
preview = if record.published? && !model[:ancestry] | ||
controller.main_app.page_path(record.to_preview_param, | ||
locale: locale) | ||
else | ||
controller.main_app.page_path(record.to_preview_param, | ||
locale: locale, | ||
Folio::Publishable::PREVIEW_PARAM_NAME => record.preview_token) | ||
end | ||
|
||
actions({ preview: }, :edit, :destroy, :clone) | ||
elsif record.is_a?(Folio::Page) && record.class.try(:public_rails_path) | ||
actions({ preview: controller.main_app.send(record.class.public_rails_path, locale: locale) }, | ||
:edit, | ||
:destroy) | ||
else | ||
actions(:edit, :destroy) | ||
end | ||
|
||
transportable_dropdown | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nemelo by byt pri zmene |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
|
||
class Folio::ClonableTest < ActiveSupport::TestCase | ||
test "create clone of page" do | ||
page = create(:folio_page) | ||
|
||
create_atom(Dummy::Atom::Contents::Text, | ||
placement: page, | ||
content: "Původní text") | ||
|
||
image = create(:folio_file_image) | ||
|
||
create_atom(Dummy::Atom::Cards::Image, | ||
placement: page, | ||
title: "Původní titulek", | ||
description: "Původní popis", | ||
url: "https://example.com", | ||
cover: image) | ||
page.cover = image | ||
|
||
original_attributes = page.attributes | ||
clone = page.create_clone | ||
|
||
clone.title = "clone" | ||
assert clone.valid? | ||
|
||
assert_not_equal page.atoms, clone.atoms | ||
assert_equal page.cover, clone.cover | ||
assert_not_equal page.cover_placement, clone.cover_placement | ||
|
||
clone.atoms.first.update!(content: "Změněný text") | ||
clone.atoms.last.update!(title: "Změněný titulek", description: "Změněný popis", url: "https://example2.com") | ||
|
||
clone.update!( | ||
title: "Nový titulek", | ||
perex: "Nový perex", | ||
published_at: Time.current, | ||
published: true, | ||
) | ||
|
||
page.reload | ||
assert_equal original_attributes, page.attributes | ||
assert_equal "Původní text", page.atoms.first.content | ||
assert_not_equal page.atoms.first.content, clone.atoms.first.content | ||
assert_equal image, page.atoms.second.cover | ||
assert_equal image, clone.atoms.second.cover | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
podle nejake tridni metody bych to zaroven pridal pro patricne tridy do
default_actions