trusty-cms 7.0.31 → 7.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6638d8ed6e3b9f192675721e595bc6ed217eed616e2e3b869531b405b4afe32
4
- data.tar.gz: 4cf9d0d42e6549677a391b661c95214071a1ca1e38d5e00e58e83e966946e89f
3
+ metadata.gz: fcafb280a56612c280982244b9a3bc76e4460aabef9ea7bb28eed7cdccfd880c
4
+ data.tar.gz: 281618eabbfbf3c6b14dba86edc1ce57aa5d362607c7e68f4aab09ad81a4fbca
5
5
  SHA512:
6
- metadata.gz: 5869e4913fa6901c264e224fc8fe5da3f32758f2a8b371fe6e74b3e93f7e2be45b4945733afc32681e79a7bd9c6ae2fe74f91f3189405ef17d2f5e58fe241900
7
- data.tar.gz: 2c5eb337819e07bda79023a9c969c4f277253013a5e1881dc2efd23f4d9ac4235fe1490dd81d391cc249abecf26e1b33e44b8fab6940763fe218251d1ac3cace
6
+ metadata.gz: bf4134454382b20f1e8bad14286963d02fa3dd7079ab3786516408e1a744514a147e58bfdd3f4ae60c2e355f252aa4bc6cab8fb22a8315f924aba6303a9f30ac
7
+ data.tar.gz: 27bce35c3fb49517d7af5825049bf68e40ca0af29c117f60aca5066c005080cc5e8e3fa4c60dc78691d9c5898299f5b3c286851bd6a23644c7253b3478cc7a1a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- trusty-cms (7.0.31)
4
+ trusty-cms (7.0.32)
5
5
  RedCloth (= 4.3.3)
6
6
  activestorage-validator
7
7
  acts_as_list (>= 0.9.5, < 1.3.0)
@@ -12,6 +12,7 @@ PATH
12
12
  delocalize (>= 0.2, < 2.0)
13
13
  devise
14
14
  devise-two-factor
15
+ diffy
15
16
  drb
16
17
  execjs (~> 2.7)
17
18
  haml (>= 5.0, < 6.0)
@@ -168,6 +169,7 @@ GEM
168
169
  railties (>= 7.0, < 8.1)
169
170
  rotp (~> 6.0)
170
171
  diff-lcs (1.5.1)
172
+ diffy (3.4.4)
171
173
  docile (1.4.1)
172
174
  drb (2.2.1)
173
175
  erubi (1.13.0)
@@ -246,6 +248,7 @@ GEM
246
248
  mime-types-data (3.2024.1105)
247
249
  mini_magick (4.13.2)
248
250
  mini_mime (1.1.5)
251
+ mini_portile2 (2.8.9)
249
252
  mini_racer (0.16.0)
250
253
  libv8-node (~> 18.19.0.0)
251
254
  minitest (5.25.4)
@@ -264,17 +267,24 @@ GEM
264
267
  net-smtp (0.5.0)
265
268
  net-protocol
266
269
  nio4r (2.7.3)
267
- nokogiri (1.17.2-aarch64-linux)
270
+ nokogiri (1.18.8)
271
+ mini_portile2 (~> 2.8.2)
268
272
  racc (~> 1.4)
269
- nokogiri (1.17.2-arm-linux)
273
+ nokogiri (1.18.8-aarch64-linux-gnu)
270
274
  racc (~> 1.4)
271
- nokogiri (1.17.2-arm64-darwin)
275
+ nokogiri (1.18.8-aarch64-linux-musl)
272
276
  racc (~> 1.4)
273
- nokogiri (1.17.2-x86-linux)
277
+ nokogiri (1.18.8-arm-linux-gnu)
274
278
  racc (~> 1.4)
275
- nokogiri (1.17.2-x86_64-darwin)
279
+ nokogiri (1.18.8-arm-linux-musl)
276
280
  racc (~> 1.4)
277
- nokogiri (1.17.2-x86_64-linux)
281
+ nokogiri (1.18.8-arm64-darwin)
282
+ racc (~> 1.4)
283
+ nokogiri (1.18.8-x86_64-darwin)
284
+ racc (~> 1.4)
285
+ nokogiri (1.18.8-x86_64-linux-gnu)
286
+ racc (~> 1.4)
287
+ nokogiri (1.18.8-x86_64-linux-musl)
278
288
  racc (~> 1.4)
279
289
  orm_adapter (0.5.0)
280
290
  paper_trail (16.0.0)
@@ -0,0 +1,17 @@
1
+ document.addEventListener("DOMContentLoaded", () => {
2
+ document.querySelectorAll(".toggle-diff").forEach(link => {
3
+ link.addEventListener("click", event => {
4
+ event.preventDefault();
5
+
6
+ const targetId = link.dataset.toggle;
7
+ const row = document.getElementById(targetId);
8
+ if (!row) return;
9
+
10
+ const isHidden = window.getComputedStyle(row).display === "none";
11
+ row.style.display = isHidden ? "table-row" : "none";
12
+
13
+ link.textContent = isHidden ? "Hide Diff" : "Show Diff";
14
+ link.setAttribute("aria-expanded", isHidden.toString());
15
+ });
16
+ });
17
+ });
@@ -29,6 +29,7 @@
29
29
  //= require 'admin/pagefield'
30
30
  //= require 'admin/popup'
31
31
  //= require 'admin/preview'
32
+ //= require 'admin/recent-changes'
32
33
  //= require 'admin/tabcontrol'
33
34
  //= require 'admin/utilities'
34
35
  //= require 'admin/tags'
@@ -28,6 +28,7 @@
28
28
  @import "partials/treetable";
29
29
  @import "partials/login_form";
30
30
  @import "partials/previous_versions";
31
+ @import "partials/recent_changes";
31
32
  @import "multi_site_main";
32
33
  @import "site_chooser";
33
34
 
@@ -0,0 +1,80 @@
1
+ .diff {
2
+ overflow: visible;
3
+ }
4
+
5
+ .diff ul {
6
+ background: #fff;
7
+ display: table;
8
+ font-size: 13px;
9
+ list-style: none;
10
+ margin: 0;
11
+ overflow: auto;
12
+ padding: 0;
13
+ width: 100%;
14
+ }
15
+
16
+ .diff li {
17
+ display: table-row;
18
+ height: 1em;
19
+ margin: 0;
20
+ padding: 0;
21
+ }
22
+
23
+ .diff li.ins {
24
+ background: #dfd;
25
+ color: #080;
26
+ }
27
+
28
+ .diff li.del {
29
+ background: #fee;
30
+ color: #b00;
31
+ }
32
+
33
+ .diff del,
34
+ .diff ins,
35
+ .diff span {
36
+ display: block;
37
+ font-family: courier;
38
+ text-decoration: none;
39
+ white-space: pre-wrap;
40
+ }
41
+
42
+ .diff del strong {
43
+ background: #fcc;
44
+ font-weight: normal;
45
+ }
46
+
47
+ .diff ins strong {
48
+ background: #9f9;
49
+ font-weight: normal;
50
+ }
51
+
52
+ .diff li.diff-comment {
53
+ display: none;
54
+ }
55
+
56
+ .diff li.diff-block-info {
57
+ background: gray;
58
+ }
59
+
60
+ .dynamic-diff-row {
61
+ display: none;
62
+ }
63
+
64
+ table#recent-changes {
65
+ width: 100%;
66
+ }
67
+
68
+ table#recent-changes td {
69
+ overflow-wrap: break-word;
70
+ padding: 12px;
71
+ word-break: break-word;
72
+ }
73
+
74
+ table#recent-changes tr:hover.diff-row td {
75
+ background: none !important;
76
+ }
77
+
78
+ table#recent-changes tr:hover.dynamic-diff-row td {
79
+ background: none !important;
80
+ }
@@ -7,7 +7,6 @@
7
7
  width: $width;
8
8
  }
9
9
 
10
-
11
10
  table {
12
11
  th {
13
12
  background-color: $light-gray;
@@ -51,23 +50,23 @@ table {
51
50
  color: $dark-gray;
52
51
  text-decoration: none;
53
52
 
53
+ &.selected,
54
54
  &:hover {
55
55
  background: $light-gray;
56
56
  border: 1px solid darken($light-gray, 10%);
57
57
  margin: 0 24px 0 0;
58
58
  }
59
-
60
- &.selected {
61
- background: $light-gray;
62
- border: 1px solid darken($light-gray, 10%);
63
- margin: 0 24px 0 0;
64
- }
65
59
  }
66
60
 
67
61
  span.action.disabled {
68
62
  color: #cccccc;
69
63
  }
70
64
 
65
+ &.actions {
66
+ font-size: 85%;
67
+ white-space: nowrap;
68
+ }
69
+
71
70
  &.empty {
72
71
  color: silver;
73
72
  font-style: italic;
@@ -83,10 +82,12 @@ table {
83
82
  text-decoration: none;
84
83
  }
85
84
  }
85
+ }
86
86
 
87
- &.actions {
88
- font-size: 85%;
89
- white-space: nowrap;
87
+ thead {
88
+ tr,
89
+ tr:first-child {
90
+ border-top: none;
90
91
  }
91
92
  }
92
93
 
@@ -104,17 +105,17 @@ table {
104
105
  }
105
106
  }
106
107
  }
107
-
108
- thead {
109
- tr,
110
- tr:first-child {
111
- border-top: none;
112
- }
113
- }
114
108
  }
115
109
 
116
110
  table.index#pages {
117
111
  td.name {
112
+ .info {
113
+ color: #9eb3bf;
114
+ font-size: 0.90em;
115
+ font-style: italic;
116
+ font-weight: normal;
117
+ }
118
+
118
119
  .w1 {
119
120
  position: relative;
120
121
 
@@ -124,24 +125,35 @@ table.index#pages {
124
125
  position: absolute;
125
126
  }
126
127
  }
128
+ }
127
129
 
128
- .info {
129
- color: #9eb3bf;
130
- font-size: 0.90em;
131
- font-style: italic;
132
- font-weight: normal;
133
- }
130
+ td.status {
131
+ font-size: 0.80em;
134
132
  }
135
133
 
136
134
  tr.page.virtual td.name a .title {
137
135
  color: #9eb3bf;
138
136
  }
137
+ }
139
138
 
140
- td.status {
141
- font-size: .80em;
139
+ table.index#users {
140
+ td.name {
141
+ padding-bottom: 8px;
142
+ padding-top: 8px;
143
+
144
+ .login {
145
+ color: #9eb3bf;
146
+ font-size: 90%;
147
+ font-style: italic;
148
+ font-weight: normal;
149
+ }
142
150
  }
143
151
  }
144
152
 
153
+ table#versions-table td {
154
+ padding: 12px;
155
+ }
156
+
145
157
  .status {
146
158
  a {
147
159
  @include plain-link;
@@ -155,17 +167,3 @@ table.index#pages {
155
167
  .hidden_status {
156
168
  @include status-badge(#9eb3bf);
157
169
  }
158
-
159
- table.index#users {
160
- td.name {
161
- padding-bottom: 8px;
162
- padding-top: 8px;
163
-
164
- .login {
165
- color: #9eb3bf;
166
- font-size: 90%;
167
- font-style: italic;
168
- font-weight: normal;
169
- }
170
- }
171
- }
@@ -0,0 +1,118 @@
1
+ require 'diffy'
2
+
3
+ class Admin::ChangesController < Admin::ResourceController
4
+ before_action :initialize_variables
5
+
6
+ def show
7
+ @changes = load_changes
8
+ @change_error = 'Version ID not found.' if params[:version_id].present? && @changes.empty?
9
+ end
10
+
11
+ private
12
+
13
+ def load_changes
14
+ return load_single_change if params[:version_id].present?
15
+
16
+ load_recent_changes
17
+ end
18
+
19
+ def load_single_change
20
+ version = PaperTrail::Version.find_by(id: params[:version_id])
21
+ version ? [build_change_entry(version)] : []
22
+ end
23
+
24
+ def load_recent_changes
25
+ fetch_recent_page_versions.map { |version| build_change_entry(version) }
26
+ end
27
+
28
+ def fetch_recent_page_versions
29
+ PaperTrail::Version.
30
+ where(item_type: 'Page').
31
+ joins('INNER JOIN pages ON pages.id = versions.item_id').
32
+ where(pages: { site_id: current_site.id }).
33
+ where('versions.created_at >= ?', 1.month.ago).
34
+ order(created_at: :desc).
35
+ limit(25)
36
+ end
37
+
38
+ def build_change_entry(version)
39
+ page = Page.find_by(id: version.item_id)
40
+ return {} unless page
41
+
42
+ {
43
+ action: version.event.titleize,
44
+ diff: build_diff(version),
45
+ id: version.id,
46
+ page_title: page.title,
47
+ page_url: admin_page_url(page),
48
+ updated_at: format_timestamp(version.created_at),
49
+ user_name: user_name(version.whodunnit),
50
+ }
51
+ end
52
+
53
+ def build_diff(version)
54
+ related_versions = PaperTrail::Version.where(transaction_id: version.transaction_id)
55
+ diffs = related_versions.flat_map { |v| diff_fields(v) }.compact
56
+ diffs.any? ? diffs.join('<br />') : nil
57
+ end
58
+
59
+ def diff_fields(version)
60
+ version.changeset.map do |field, (old_val, new_val)|
61
+ next unless renderable_diff?(field, old_val, new_val)
62
+
63
+ render_field_diff(version, field, old_val, new_val)
64
+ end
65
+ end
66
+
67
+ def renderable_diff?(field, old_val, new_val)
68
+ !ignored_fields.include?(field) && !(old_val.nil? && new_val == '')
69
+ end
70
+
71
+ def render_field_diff(version, field, old_val, new_val)
72
+ diff_html = Diffy::Diff.new(old_val, new_val, context: 1).to_s(:html)
73
+
74
+ label = version.item_type == 'Page' ? field : label_for_version(version)
75
+ "<h2>#{label.humanize.titleize}</h2>#{diff_html}"
76
+ end
77
+
78
+ def ignored_fields
79
+ %w[
80
+ created_at
81
+ created_by_id
82
+ id
83
+ lock_version
84
+ name
85
+ page_id
86
+ published_at
87
+ updated_at
88
+ updated_by_id
89
+ ].freeze
90
+ end
91
+
92
+ def user_name(whodunnit)
93
+ user_id = Integer(whodunnit, exception: false)
94
+ User.find_by(id: user_id)&.name || 'Unknown User'
95
+ end
96
+
97
+ def label_for_version(version)
98
+ case version.item_type
99
+ when 'PagePart' then PagePart.find_by(id: version.item_id)&.name || 'Unknown PagePart'
100
+ when 'PageField' then PageField.find_by(id: version.item_id)&.name || 'Unknown PageField'
101
+ else version.item_type
102
+ end
103
+ end
104
+
105
+ def format_timestamp(timestamp)
106
+ timestamp.strftime('%A, %B %d, %I:%M %p')
107
+ end
108
+
109
+ def admin_page_url(page)
110
+ "/admin/pages/#{page.id}"
111
+ end
112
+
113
+ def initialize_variables
114
+ @user = current_user
115
+ @controller_name = 'changes'
116
+ @template_name = 'show'
117
+ end
118
+ end
@@ -134,6 +134,7 @@ class Admin::PagesController < Admin::ResourceController
134
134
  .sort_by(&:created_at).reverse
135
135
  .map do |version|
136
136
  {
137
+ id: version&.id,
137
138
  index: version&.index,
138
139
  update_date: version&.created_at&.strftime('%B %d, %Y'),
139
140
  update_time: version&.created_at&.strftime('%I:%M %p'),
@@ -9,6 +9,7 @@ class Admin::ResourceController < ApplicationController
9
9
  before_action :load_models, only: :index
10
10
  before_action :load_model, only: %i[new create edit update remove destroy]
11
11
  before_action :set_owner_or_editor, only: %i[new create update]
12
+ before_action :set_page_updated_at, only: :update
12
13
  after_action :clear_model_cache, only: %i[create update destroy]
13
14
 
14
15
  cattr_reader :paginated
@@ -145,6 +146,12 @@ class Admin::ResourceController < ApplicationController
145
146
  end
146
147
  end
147
148
 
149
+ def set_page_updated_at
150
+ if model.class.name.include?('Page') && model.has_attribute?(:updated_at)
151
+ model.updated_at = Time.zone.now
152
+ end
153
+ end
154
+
148
155
  def model
149
156
  instance_variable_get("@#{model_symbol}") || load_model
150
157
  end
@@ -25,4 +25,10 @@ module Admin::PagesHelper
25
25
  selected_page_id = page.parent_id
26
26
  options_for_select(parent_pages.map { |p| [p.title, p.id] }, selected_page_id)
27
27
  end
28
+
29
+ def revert_confirmation_message(version)
30
+ date = version[:update_date]
31
+ time = version[:update_time]
32
+ "Are you sure you want to revert the page to the version before the change made on #{date} at #{time}? All changes made after that will be lost."
33
+ end
28
34
  end
data/app/models/page.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  require 'trusty_cms/taggable'
2
2
 
3
3
  class Page < ActiveRecord::Base
4
- has_paper_trail
5
-
6
4
  class MissingRootPageError < StandardError
7
5
  def initialize(message = 'Database missing root page')
8
6
  ; super
@@ -22,6 +20,8 @@ class Page < ActiveRecord::Base
22
20
  belongs_to :created_by, class_name: 'User'
23
21
  belongs_to :updated_by, class_name: 'User'
24
22
 
23
+ has_paper_trail
24
+
25
25
  # Validations
26
26
  validates_presence_of :title, :slug, :breadcrumb, :status_id
27
27
 
@@ -40,6 +40,7 @@ class Page < ActiveRecord::Base
40
40
 
41
41
  annotate :description
42
42
  attr_accessor :request, :response, :pagination_parameters
43
+
43
44
  class_attribute :default_child
44
45
  self.default_child = self
45
46
 
@@ -264,11 +265,11 @@ class Page < ActiveRecord::Base
264
265
  @display_name = string
265
266
  else
266
267
  @display_name ||= begin
267
- n = name.to_s
268
- n.sub(/^(.+?)Page$/, '\1')
269
- n.gsub(/([A-Z])/, ' \1')
270
- n.strip
271
- end
268
+ n = name.to_s
269
+ n.sub(/^(.+?)Page$/, '\1')
270
+ n.gsub(/([A-Z])/, ' \1')
271
+ n.strip
272
+ end
272
273
  end
273
274
  @display_name = @display_name + ' - not installed' if missing? && @display_name !~ /not installed/
274
275
  @display_name
@@ -1,12 +1,12 @@
1
1
  class PagePart < ActiveRecord::Base
2
- has_paper_trail
3
-
4
2
  # Default Order
5
3
  default_scope { order('name') }
6
4
 
7
5
  # Associations
8
6
  belongs_to :page
9
7
 
8
+ has_paper_trail
9
+
10
10
  # Validations
11
11
  validates_presence_of :name
12
12
  validates_length_of :name, maximum: 100
@@ -0,0 +1,57 @@
1
+ - @page_title = 'Changes - ' + default_page_title
2
+ - single_change = params[:version_id].present?
3
+
4
+ .outset
5
+ = render_region :top
6
+
7
+ %table#recent-changes
8
+ %thead
9
+ %tr
10
+ %th Version ID
11
+ %th Title
12
+ %th Action
13
+ %th User
14
+ %th Updated At
15
+
16
+ %tbody
17
+ - if @change_error
18
+ %tr
19
+ %td{ colspan: 5 }
20
+ %span.text-danger= @change_error
21
+
22
+ - elsif @changes.present?
23
+ - @changes.each_with_index do |change, index|
24
+ %tr.change-row{ data: { toggle_target: "diff-#{index}" } }
25
+ %td= change[:id]
26
+ %td= link_to change[:page_title], change[:page_url]
27
+ %td= change[:action]
28
+ %td= change[:user_name]
29
+ %td
30
+ = change[:updated_at]
31
+ - unless single_change
32
+ %br
33
+ %a.toggle-diff{
34
+ href: "#",
35
+ role: "button",
36
+ tabindex: "0",
37
+ aria: {
38
+ expanded: "false",
39
+ controls: "diff-#{index}"
40
+ },
41
+ data: { toggle: "diff-#{index}" }
42
+ } Show Diff
43
+
44
+ - diff_row_id = single_change ? nil : "diff-#{index}"
45
+ - diff_row_class = single_change ? 'diff-row' : 'dynamic-diff-row'
46
+ %tr{ id: diff_row_id, class: diff_row_class, role: "region", "aria-live" => "polite" }
47
+ %td{ colspan: 5 }
48
+ - if change[:diff].present?
49
+ != change[:diff]
50
+ - else
51
+ %span.text-muted No differences found.
52
+ %span.sr-only Diff details for version ID #{change[:id]}.
53
+
54
+ - else
55
+ %tr
56
+ %td{ colspan: 5 }
57
+ %span No recent changes.
@@ -1,4 +1,4 @@
1
- - if current_user.scoped_site? && defined?(Site) && defined?(controller) && controller.sited_model? && Site.several?
1
+ - if current_user.scoped_site? && defined?(Site) && defined?(controller) && Site.several?
2
2
  .site_chooser
3
3
  %ul.nav
4
4
  %li
@@ -3,31 +3,40 @@
3
3
  %h4
4
4
  %i.fas.fa-clock-rotate-left
5
5
  Previous Versions
6
+
6
7
  .drawer_contents#versions
7
8
  - if @versions.present?
8
9
  %section
9
- %table
10
+ %table#versions-table
10
11
  %thead
11
12
  %tr
13
+ %th Version ID
12
14
  %th Date Updated
13
15
  %th Time Updated
14
16
  %th Updated By
15
17
  %th Action
16
- %tbody{ :id => 'versions-table' }
18
+ %tbody
17
19
  - @versions.each do |version|
18
20
  %tr
21
+ %td= link_to version[:id], admin_changes_path(version_id: version[:id])
19
22
  %td= version[:update_date]
20
23
  %td= version[:update_time]
21
24
  %td= version[:updated_by]
22
25
  %td
23
- = button_to 'Restore',
26
+ = button_to 'Undo',
24
27
  restore_version_admin_page_path(@page, version_index: version[:index]),
25
28
  method: :put,
26
- data: { confirm: 'Are you sure you want to restore this version?' }
29
+ class: 'btn btn-warning',
30
+ data: { confirm: revert_confirmation_message(version) }
27
31
  - else
28
32
  %section#no-previous-versions
29
33
  %p No previous versions are available.
34
+
30
35
  .drawer_handle
31
- %a.toggle{:href=>'#versions', :rel=>'toggle[versions]', :class=>"#{(meta_errors? ? 'less' : 'more')}"}
36
+ %a.toggle{
37
+ href: '#versions',
38
+ rel: 'toggle[versions]',
39
+ class: (meta_errors? ? 'less' : 'more')
40
+ }
32
41
  = meta_label
33
42
  %i.fas.fa-angle-down
data/config/routes.rb CHANGED
@@ -43,6 +43,7 @@ TrustyCms::Application.routes.draw do
43
43
  get 'admin' => 'admin/pages#index'
44
44
 
45
45
  namespace :admin do
46
+ resource :changes
46
47
  resource :preferences
47
48
  resource :two_factor, only: [:show, :create], controller: 'two_factor', path: 'two-factor'
48
49
  resource :security, controller: 'security' do
@@ -0,0 +1,8 @@
1
+ class AddObjectChangesToVersions < ActiveRecord::Migration[7.0]
2
+ # The largest text column available in all supported RDBMS.
3
+ TEXT_BYTES = 1_073_741_823
4
+
5
+ def change
6
+ add_column :versions, :object_changes, :text, limit: TEXT_BYTES
7
+ end
8
+ end
@@ -124,7 +124,7 @@ module TrustyCms
124
124
  end
125
125
 
126
126
  # Region sets
127
- %w{page layout user configuration extension}.each do |controller|
127
+ %w{page layout user changes configuration extension}.each do |controller|
128
128
  attr_accessor controller
129
129
  alias_method "#{controller}s", controller
130
130
  end
@@ -148,6 +148,10 @@ module TrustyCms
148
148
  design << nav_item('Layouts', '/admin/layouts')
149
149
  nav << design
150
150
 
151
+ changes = nav_tab('Recent Changes')
152
+ changes << nav_item('Changes', '/admin/changes')
153
+ nav << changes
154
+
151
155
  settings = nav_tab('Settings')
152
156
  settings << nav_item('General', '/admin/configuration')
153
157
  settings << nav_item('Personal', '/admin/preferences')
@@ -160,6 +164,7 @@ module TrustyCms
160
164
  def load_default_regions
161
165
  @page = load_default_page_regions
162
166
  @layout = load_default_layout_regions
167
+ @changes = load_default_changes_regions
163
168
  @user = load_default_user_regions
164
169
  @configuration = load_default_configuration_regions
165
170
  @extension = load_default_extension_regions
@@ -233,6 +238,14 @@ module TrustyCms
233
238
  end
234
239
  end
235
240
 
241
+ def load_default_changes_regions
242
+ OpenStruct.new.tap do |changes|
243
+ changes.show = RegionSet.new do |show|
244
+ show.top.concat %w{}
245
+ end
246
+ end
247
+ end
248
+
236
249
  def load_default_configuration_regions
237
250
  OpenStruct.new.tap do |configuration|
238
251
  configuration.show = RegionSet.new do |show|
@@ -1,3 +1,3 @@
1
1
  module TrustyCms
2
- VERSION = '7.0.31'.freeze
2
+ VERSION = '7.0.32'.freeze
3
3
  end
data/trusty_cms.gemspec CHANGED
@@ -34,6 +34,7 @@ a general purpose content management system--not merely a blogging engine.'
34
34
  s.add_dependency 'delocalize', '>= 0.2', '< 2.0'
35
35
  s.add_dependency 'devise'
36
36
  s.add_dependency 'devise-two-factor'
37
+ s.add_dependency 'diffy'
37
38
  s.add_dependency 'drb'
38
39
  s.add_dependency 'execjs', '~> 2.7'
39
40
  s.add_dependency 'haml', '>= 5.0', '< 6.0'
@@ -21,10 +21,12 @@ class MultiSiteExtension < TrustyCms::Extension
21
21
  Admin::PagesController.send :include, MultiSite::PagesControllerExtensions
22
22
  Admin::ResourceController.send :helper, MultiSite::SiteChooserHelper
23
23
  Admin::PagesController.send :helper, MultiSite::SiteChooserHelper
24
+ Admin::ChangesController.send :helper, MultiSite::SiteChooserHelper
24
25
  admin.layouts.index.add(:before_nav, "admin/layouts/site_chooser")
25
26
  admin.pages.index.add(:before_nav, "admin/layouts/site_chooser")
26
27
  admin.snippets.index.add(:before_nav, "admin/layouts/site_chooser")
27
28
  admin.pages.search.add(:before_nav, "admin/layouts/site_chooser")
29
+ admin.changes.show.add(:before_nav, "admin/layouts/site_chooser")
28
30
  Layout.send :is_site_scoped
29
31
  Snippet.send :is_site_scoped
30
32
  User.send :is_site_scoped, :shareable => true
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trusty-cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.31
4
+ version: 7.0.32
5
5
  platform: ruby
6
6
  authors:
7
7
  - TrustyCms CMS dev team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-09 00:00:00.000000000 Z
11
+ date: 2025-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activestorage-validator
@@ -154,6 +154,20 @@ dependencies:
154
154
  - - ">="
155
155
  - !ruby/object:Gem::Version
156
156
  version: '0'
157
+ - !ruby/object:Gem::Dependency
158
+ name: diffy
159
+ requirement: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ type: :runtime
165
+ prerelease: false
166
+ version_requirements: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
157
171
  - !ruby/object:Gem::Dependency
158
172
  name: drb
159
173
  requirement: !ruby/object:Gem::Requirement
@@ -731,6 +745,7 @@ files:
731
745
  - app/assets/javascripts/admin/persist.min.js
732
746
  - app/assets/javascripts/admin/popup.js
733
747
  - app/assets/javascripts/admin/preview.js
748
+ - app/assets/javascripts/admin/recent-changes.js
734
749
  - app/assets/javascripts/admin/sortable.js
735
750
  - app/assets/javascripts/admin/tabcontrol.js.erb
736
751
  - app/assets/javascripts/admin/tags.js
@@ -765,6 +780,7 @@ files:
765
780
  - app/assets/stylesheets/admin/partials/_popup.scss
766
781
  - app/assets/stylesheets/admin/partials/_preferences.scss
767
782
  - app/assets/stylesheets/admin/partials/_previous_versions.scss
783
+ - app/assets/stylesheets/admin/partials/_recent_changes.scss
768
784
  - app/assets/stylesheets/admin/partials/_sidebar.scss
769
785
  - app/assets/stylesheets/admin/partials/_tabcontrol.scss
770
786
  - app/assets/stylesheets/admin/partials/_table.scss
@@ -773,6 +789,7 @@ files:
773
789
  - app/assets/stylesheets/admin/partials/_typography.scss
774
790
  - app/assets/stylesheets/admin/partials/_validations.scss
775
791
  - app/controllers/admin/assets_controller.rb
792
+ - app/controllers/admin/changes_controller.rb
776
793
  - app/controllers/admin/configuration_controller.rb
777
794
  - app/controllers/admin/extensions_controller.rb
778
795
  - app/controllers/admin/layouts_controller.rb
@@ -848,6 +865,7 @@ files:
848
865
  - app/views/admin/assets/index.html.haml
849
866
  - app/views/admin/assets/new.html.haml
850
867
  - app/views/admin/assets/remove.html.haml
868
+ - app/views/admin/changes/show.html.haml
851
869
  - app/views/admin/configuration/_clipped_edit.html.haml
852
870
  - app/views/admin/configuration/_clipped_show.html.haml
853
871
  - app/views/admin/configuration/edit.html.haml
@@ -1002,6 +1020,7 @@ files:
1002
1020
  - db/migrate/20250103191133_create_version_associations.rb
1003
1021
  - db/migrate/20250103191134_add_transaction_id_column_to_versions.rb
1004
1022
  - db/migrate/20250502162215_add_devise_two_factor_to_admins.rb
1023
+ - db/migrate/20250606144908_add_object_changes_to_versions.trusty_cms.rb
1005
1024
  - db/schema.rb
1006
1025
  - lib/active_record_extensions/active_record_extensions.rb
1007
1026
  - lib/annotatable.rb