<% attribute_change_events = content.raw_model.attribute_change_events changed_attributes = Attribute.where(id: attribute_change_events.select { |event| event.content_type == 'Attribute' }.map(&:content_id)) changed_fields = AttributeField.where(id: changed_attributes.pluck(:attribute_field_id)).includes([:attribute_category]) %>

Recent changes for <%= link_to content.name, polymorphic_path(content.raw_model) %>

<% attribute_change_events.reverse.each do |change_event| %> <% # Some of the really old events (4+ years ago) don't have a user. We can just skip those. next if change_event.user.nil? %> <% change_event.changed_fields.each do |field_key, change| %> <% related_attribute = changed_attributes.detect { |attribute| attribute.id == change_event.content_id } %> <% related_field = changed_fields.detect { |field| field.id == related_attribute.attribute_field_id } %> <% related_category = related_field.attribute_category %> <% # Skip field changes if the value didn't actually change next if change.first == change.second # Skip field changes if the value only changed from one blank value to another next if change.first.blank? && change.second.blank? # Don't show ContentChangeEvents for excluded fields like updated_at, etc next if ContentChangeEvent::FIELD_IDS_TO_EXCLUDE.include?(field_key) %> <% old_value = change.first.blank? ? ContentChangeEvent::BLANK_PLACEHOLDER : change.first.to_s new_value = change.second.blank? ? ContentChangeEvent::BLANK_PLACEHOLDER : change.second.to_s visible_change = true if related_field.label.start_with?('Private') # todo actual privacy flag on attributes visible_change = user_signed_in? && ( (content.raw_model.is_a?(Universe) && content.user == current_user) || (content.respond_to?(:universe) && content.universe && content.universe.user == current_user) || (content.respond_to?(:universe) && content.universe.nil? && content.user == current_user) ) end unless visible_change old_value = ContentChangeEvent::PRIVATE_PLACEHOLDER new_value = ContentChangeEvent::PRIVATE_PLACEHOLDER end # Just for clarity / ease of mind to users -- we treat blank on privacy field as "private", but that's not obvious to them. if related_field.label.downcase == 'privacy' old_value = 'private' if old_value == ContentChangeEvent::BLANK_PLACEHOLDER new_value = 'private' if new_value == ContentChangeEvent::BLANK_PLACEHOLDER end %>
<%= related_category.icon %> <%= related_category.label %> <%= related_field.label %> <%= change_event.action %> by <%= link_to(change_event.user.display_name, change_event.user, class: "#{User.text_color}") %>
<%= time_ago_in_words change_event.created_at %> ago · <%= change_event.created_at.strftime('%B %d, %H:%M %Z') %>
<%= render partial: "content/changelog/field_change/#{related_field.field_type}", locals: { old_value: old_value, new_value: new_value } %>
<% end %> <% end %> <% if content.user.present? %>
<%= content.class_name %> <%= content.name %> was created by <%= link_to content.user.name, content.user %> <%= time_ago_in_words content.raw_model.created_at %> ago.
<% end %>