app/controllers/admin/changes_controller.rb
require 'diffy' class Admin::ChangesController < Admin::ResourceController before_action :initialize_variables def show @changes = load_changes @change_error = 'Version ID not found.' if params[:version_id].present? && @changes.empty? end private def load_changes return load_single_change if params[:version_id].present? load_recent_changes end def load_single_change version = PaperTrail::Version.find_by(id: params[:version_id]) version ? [build_change_entry(version)] : [] end def load_recent_changes fetch_recent_page_versions.map { |version| build_change_entry(version) } end def fetch_recent_page_versions PaperTrail::Version. where(item_type: 'Page'). joins('INNER JOIN pages ON pages.id = versions.item_id'). where(pages: { site_id: current_site.id }). where('versions.created_at >= ?', 1.month.ago). order(created_at: :desc). limit(25) end def build_change_entry(version) page = Page.find_by(id: version.item_id) return {} unless page { action: version.event.titleize, diff: build_diff(version), id: version.id, page_title: page.title, page_url: admin_page_url(page), updated_at: format_timestamp(version.created_at), user_name: user_name(version.whodunnit), } end def build_diff(version) related_versions = PaperTrail::Version.where(transaction_id: version.transaction_id) diffs = related_versions.flat_map { |v| diff_fields(v) }.compact diffs.any? ? diffs.join('<br />') : nil end def diff_fields(version) version.changeset.map do |field, (old_val, new_val)| next unless renderable_diff?(field, old_val, new_val) render_field_diff(version, field, old_val, new_val) end end def renderable_diff?(field, old_val, new_val) !ignored_fields.include?(field) && !(old_val.nil? && new_val == '') end def render_field_diff(version, field, old_val, new_val) diff_html = Diffy::Diff.new(old_val, new_val, context: 1).to_s(:html) label = version.item_type == 'Page' ? field : label_for_version(version) "<h2>#{label.humanize.titleize}</h2>#{diff_html}" end def ignored_fields %w[ created_at created_by_id id lock_version name page_id published_at updated_at updated_by_id ].freeze end def user_name(whodunnit) user_id = Integer(whodunnit, exception: false) User.find_by(id: user_id)&.name || 'Unknown User' end def label_for_version(version) case version.item_type when 'PagePart' then PagePart.find_by(id: version.item_id)&.name || 'Unknown PagePart' when 'PageField' then PageField.find_by(id: version.item_id)&.name || 'Unknown PageField' else version.item_type end end def format_timestamp(timestamp) timestamp.strftime('%A, %B %d, %I:%M %p') end def admin_page_url(page) "/admin/pages/#{page.id}" end def initialize_variables @user = current_user @controller_name = 'changes' @template_name = 'show' end end