paper_trail_viewer 1.0.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/{test.yml → tests.yml} +5 -12
- data/CHANGELOG.md +21 -0
- data/Gemfile +8 -0
- data/README.md +27 -14
- data/Rakefile +1 -1
- data/app/controllers/paper_trail_viewer/versions_controller.rb +5 -111
- data/app/views/paper_trail_viewer/viewer/index.html.erb +1 -1
- data/javascript/compiled.js +1 -1
- data/javascript/src/app.tsx +25 -14
- data/javascript/src/components/context_menu.tsx +61 -0
- data/javascript/src/components/controls.tsx +1 -1
- data/javascript/src/components/index.ts +1 -0
- data/javascript/src/components/version_context_menu.tsx +110 -0
- data/javascript/src/components/versions_list.tsx +37 -47
- data/javascript/src/types.ts +9 -1
- data/lib/paper_trail_viewer/data_source/active_record.rb +13 -12
- data/lib/paper_trail_viewer/data_source/base.rb +88 -0
- data/lib/paper_trail_viewer/data_source/bigquery.rb +9 -8
- data/lib/paper_trail_viewer/query.rb +23 -0
- data/lib/paper_trail_viewer/rollback.rb +20 -0
- data/lib/paper_trail_viewer/version.rb +1 -1
- data/lib/paper_trail_viewer.rb +4 -0
- data/paper_trail_viewer.gemspec +3 -12
- data/spec/app_template.rb +3 -1
- data/spec/rails_helper.rb +10 -2
- data/spec/system/paper_trail_viewer_spec.rb +79 -64
- metadata +24 -122
- data/Appraisals +0 -13
- data/gemfiles/rails_6.0_paper_trail_11.1.gemfile +0 -10
- data/gemfiles/rails_6.0_paper_trail_12.2.gemfile +0 -10
- data/gemfiles/rails_7.0_paper_trail_12.2.gemfile +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cdd2a1e7e8c5b74360c45774c08655fa6a43b89b566f02b522c68ab6b383cec6
|
4
|
+
data.tar.gz: 044157321ac96676043bd07c8f9f6322a39b965a8940ccd0f17a1efd17266753
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 016a9de897fa1867be0a1a72c7212b05167b82e7b1007b9f90ef859812b252fcc8948e4483d377746847802e16f9a7b2cee8c476d63600baf5ba97d38aad3d7c
|
7
|
+
data.tar.gz: 1bef787b7201d6358ad18f3deebfb968fe271fb6047123e4f0a9f90c4f3fe564e98c919e2db86083db7d93d191ea86fd71ca1603b504c8cc51a1c0e283f6b2c2
|
@@ -10,19 +10,12 @@ jobs:
|
|
10
10
|
fail-fast: false
|
11
11
|
matrix:
|
12
12
|
ruby:
|
13
|
-
-
|
14
|
-
- 3.
|
15
|
-
gemfile:
|
16
|
-
- gemfiles/rails_6.0_paper_trail_11.1.gemfile
|
17
|
-
- gemfiles/rails_6.0_paper_trail_12.2.gemfile
|
18
|
-
- gemfiles/rails_7.0_paper_trail_12.2.gemfile
|
19
|
-
|
20
|
-
env:
|
21
|
-
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
13
|
+
- 3.1
|
14
|
+
- 3.4
|
22
15
|
|
23
16
|
steps:
|
24
|
-
- uses: actions/checkout@
|
25
|
-
- uses:
|
17
|
+
- uses: actions/checkout@v4
|
18
|
+
- uses: ruby/setup-ruby@v1
|
26
19
|
with:
|
27
20
|
ruby-version: ${{ matrix.ruby }}
|
28
21
|
- uses: actions/cache@v1
|
@@ -34,7 +27,7 @@ jobs:
|
|
34
27
|
- uses: actions/setup-node@v2
|
35
28
|
with:
|
36
29
|
node-version: '16'
|
37
|
-
|
30
|
+
- uses: nanasess/setup-chromedriver@v2
|
38
31
|
- name: Install dependencies
|
39
32
|
run: |
|
40
33
|
bundle install --jobs 4 --retry 3
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [1.1.1] - 2024-09-03
|
8
|
+
|
9
|
+
Dropped support for Ruby 2.7
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
- missing `ostruct` dependency in newer Ruby versions
|
14
|
+
|
15
|
+
## [1.1.0] - 2022-03-27
|
16
|
+
|
17
|
+
### Added
|
18
|
+
|
19
|
+
- Basic support for custom version classes
|
20
|
+
- Rollback functionality
|
21
|
+
- Track item functionality
|
22
|
+
|
23
|
+
### Fixed
|
24
|
+
|
25
|
+
- `LoadError` with data source `ActiveRecord`
|
26
|
+
- `bin/setup` being considered a gem executable
|
27
|
+
|
7
28
|
## [1.0.0] - 2022-03-26
|
8
29
|
|
9
30
|
Initial release.
|
data/Gemfile
CHANGED
@@ -2,3 +2,11 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in paper_trail_viewer.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
gem 'capybara', '~> 3.0'
|
7
|
+
gem 'factory_bot_rails', '~> 6.0'
|
8
|
+
gem 'puma', '~> 6.0'
|
9
|
+
gem 'rake', '~> 13.0'
|
10
|
+
gem 'rspec-rails', '~> 6.0'
|
11
|
+
gem 'selenium-webdriver', '~> 4.22'
|
12
|
+
gem 'sqlite3', '~> 1.4'
|
data/README.md
CHANGED
@@ -1,23 +1,33 @@
|
|
1
1
|
[![Gem Version](https://badge.fury.io/rb/paper_trail_viewer.svg)](http://badge.fury.io/rb/paper_trail_viewer)
|
2
|
-
[![Build Status](https://github.com/jaynetics/paper_trail_viewer/workflows/tests/badge.svg)](https://github.com/jaynetics/paper_trail_viewer/actions)
|
2
|
+
[![Build Status](https://github.com/jaynetics/paper_trail_viewer/actions/workflows/tests.yml/badge.svg)](https://github.com/jaynetics/paper_trail_viewer/actions)
|
3
3
|
|
4
4
|
# PaperTrailViewer
|
5
5
|
|
6
|
-
Browse changes to records when using Ruby on Rails and the [`paper_trail`
|
6
|
+
Browse changes to records when using Ruby on Rails and the [`paper_trail`](https://github.com/paper-trail-gem/paper_trail) gem.
|
7
|
+
|
8
|
+
[
|
9
|
+
![Screenshot thumbnail showing the webapp](
|
10
|
+
https://user-images.githubusercontent.com/10758879/160241794-9b9e9552-722f-48e2-9b1d-9ad463b99020.png
|
11
|
+
)
|
12
|
+
](https://user-images.githubusercontent.com/10758879/160241664-fa1a6c08-54f1-4d32-9010-16b501b70f60.png)
|
7
13
|
|
8
14
|
## Installation
|
9
15
|
|
10
16
|
Add `paper_trail_viewer` to your bundle and add the following line to your `config/routes.rb`:
|
11
17
|
|
12
|
-
|
18
|
+
```ruby
|
19
|
+
mount PaperTrailViewer::Engine => '/changes'
|
20
|
+
```
|
13
21
|
|
14
22
|
You can pick any path. Restart the server and go to the chosen path to view your versions.
|
15
23
|
|
16
|
-
To limit access
|
24
|
+
To limit access, do something like this:
|
17
25
|
|
18
|
-
|
19
|
-
|
20
|
-
|
26
|
+
```ruby
|
27
|
+
authenticate :user, ->*{ |u| u.superadmin? } do
|
28
|
+
mount PaperTrailViewer::Engine => '/changes'
|
29
|
+
end
|
30
|
+
```
|
21
31
|
|
22
32
|
### Configuration
|
23
33
|
|
@@ -25,8 +35,15 @@ Put configuration in `config/initializers/paper_trail_viewer.rb`.
|
|
25
35
|
|
26
36
|
E.g. for linking (or not) to the whodunnit user with a custom path helper:
|
27
37
|
|
28
|
-
|
29
|
-
|
38
|
+
```ruby
|
39
|
+
PaperTrailViewer.user_path_method = :admin_path # default is :user_path
|
40
|
+
PaperTrailViewer.user_path_method = nil # don't link to the user
|
41
|
+
```
|
42
|
+
|
43
|
+
Other options are:
|
44
|
+
|
45
|
+
- `PaperTrailViewer.allow_rollback` (default is `true`)
|
46
|
+
- `PaperTrailViewer.data_source` (default is `ActiveRecord`)
|
30
47
|
|
31
48
|
## Development
|
32
49
|
|
@@ -38,11 +55,7 @@ E.g. for linking (or not) to the whodunnit user with a custom path helper:
|
|
38
55
|
|
39
56
|
### Running tests
|
40
57
|
|
41
|
-
|
42
|
-
* Run `appraisal generate`
|
43
|
-
* Run `appraisal install`
|
44
|
-
* Run `appraisal rake generate_spec_app`
|
45
|
-
* Run `appraisal rake`
|
58
|
+
`bundle exec rake`
|
46
59
|
|
47
60
|
## License
|
48
61
|
|
data/Rakefile
CHANGED
@@ -1,119 +1,13 @@
|
|
1
1
|
class PaperTrailViewer::VersionsController < ActionController::Base
|
2
2
|
# Return the queried versions as JSON.
|
3
3
|
def index
|
4
|
-
|
5
|
-
|
6
|
-
versions_as_json = versions.map { |v| version_as_json(v) }
|
7
|
-
|
8
|
-
render json: {
|
9
|
-
hasNextPage: !versions.last_page? && versions_as_json.any?,
|
10
|
-
query: query,
|
11
|
-
versions: versions_as_json,
|
12
|
-
}
|
4
|
+
result = PaperTrailViewer.data_source.call(params, main_app)
|
5
|
+
render json: result
|
13
6
|
end
|
14
7
|
|
15
|
-
#
|
8
|
+
# Roll back a change.
|
16
9
|
def update
|
17
|
-
|
18
|
-
|
19
|
-
return redirect_to(root_url)
|
20
|
-
end
|
21
|
-
|
22
|
-
result =
|
23
|
-
if version.event == 'create'
|
24
|
-
version.item_type.constantize.find(version.item_id).destroy
|
25
|
-
else
|
26
|
-
version.reify.save
|
27
|
-
end
|
28
|
-
|
29
|
-
if result
|
30
|
-
if version.event == 'create'
|
31
|
-
flash[:notice] = 'Rolled back newly-created record by destroying it.'
|
32
|
-
redirect_to root_url
|
33
|
-
else
|
34
|
-
flash[:notice] = 'Rolled back changes to this record.'
|
35
|
-
redirect_to change_item_url(version)
|
36
|
-
end
|
37
|
-
else
|
38
|
-
flash[:error] = "Couldn't rollback. Sorry."
|
39
|
-
redirect_to root_url
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def sanitized_params
|
46
|
-
{
|
47
|
-
event: params[:event].presence_in(%w[create update destroy]),
|
48
|
-
filter: (params[:filter].presence if params[:filter] != '%%'),
|
49
|
-
item_id: params[:item_id].presence,
|
50
|
-
item_type: params[:item_type].presence,
|
51
|
-
page: (page = params[:page].to_i) > 0 ? page : 1,
|
52
|
-
per_page: (per = params[:per_page].to_i).clamp(1, 1000),
|
53
|
-
}
|
54
|
-
end
|
55
|
-
|
56
|
-
def version_as_json(version)
|
57
|
-
{
|
58
|
-
**version.attributes.slice(*%w[id whodunnit event created_at]),
|
59
|
-
changeset: changeset_for(version),
|
60
|
-
object: load_object(version),
|
61
|
-
item_id: version.item_id.to_s,
|
62
|
-
item_type: version.item_type,
|
63
|
-
item_url: change_item_url(version),
|
64
|
-
user_url: user_url(version),
|
65
|
-
}
|
66
|
-
end
|
67
|
-
|
68
|
-
def changeset_for(version)
|
69
|
-
case version.event
|
70
|
-
when 'create', 'update'
|
71
|
-
version.changeset || {}
|
72
|
-
when 'destroy'
|
73
|
-
record = version.reify rescue nil
|
74
|
-
return {} unless record
|
75
|
-
|
76
|
-
record.attributes.each_with_object({}) do |changes, (k, v)|
|
77
|
-
changes[k] = [v, nil] unless v.nil?
|
78
|
-
end
|
79
|
-
else
|
80
|
-
raise ArgumentError, "Unknown event: #{version.event}"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# Return the URL for the item represented by the +version+,
|
85
|
-
# e.g. a Company record instance referenced by a version.
|
86
|
-
def change_item_url(version)
|
87
|
-
version_type = version.item_type.underscore.split('/').last
|
88
|
-
main_app.try("#{version_type}_url", version.item_id)
|
89
|
-
end
|
90
|
-
|
91
|
-
def user_url(version)
|
92
|
-
(path_method = PaperTrailViewer.user_path_method).present? &&
|
93
|
-
(id = version.whodunnit).present? &&
|
94
|
-
!id.start_with?('#') &&
|
95
|
-
main_app.try(path_method, id) ||
|
96
|
-
nil
|
97
|
-
end
|
98
|
-
|
99
|
-
def load_object(version)
|
100
|
-
obj = version.object
|
101
|
-
if obj.is_a?(String)
|
102
|
-
PaperTrail.serializer.load(obj)
|
103
|
-
elsif obj.is_a?(Hash)
|
104
|
-
OpenStruct.new(obj)
|
105
|
-
else
|
106
|
-
obj
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# backport deserialization fix for recent rubies
|
112
|
-
# https://github.com/paper-trail-gem/paper_trail/pull/1338
|
113
|
-
if PaperTrail::VERSION.to_s < '12.2.0'
|
114
|
-
module PaperTrail::Serializers::YAML
|
115
|
-
def load(string)
|
116
|
-
::YAML.respond_to?(:unsafe_load) ? ::YAML.unsafe_load(string) : ::YAML.load(string)
|
117
|
-
end
|
10
|
+
result = PaperTrailViewer::Rollback.call(version_id: params[:id])
|
11
|
+
render json: result
|
118
12
|
end
|
119
13
|
end
|