loggable_activity 0.5.0 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -0
- data/CHANGELOG.md +15 -0
- data/GETTING-STARTED.md +60 -0
- data/README.md +42 -31
- data/app/assets/config/loggable_activity_manifest.js +1 -3
- data/app/assets/javascripts/loggable_activity/application.js +0 -1
- data/app/assets/stylesheets/loggable_activity/activities.scss +25 -0
- data/app/assets/stylesheets/loggable_activity/application.scss +2 -6
- data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_first_page.html.erb +0 -1
- data/app/views/kaminari/pico/_last_page.html.erb +12 -0
- data/app/views/layouts/loggable_activity/application.html.slim +20 -0
- data/app/views/loggable_activity/activities/_activities.html.slim +28 -0
- data/app/views/loggable_activity/activities/index.html.erb +5 -6
- data/app/views/loggable_activity/bootstrap/kaminari/_first_page.html.erb +13 -0
- data/app/views/loggable_activity/bootstrap/kaminari/_gap.html.erb +8 -0
- data/app/views/loggable_activity/bootstrap/kaminari/_next_page.html.erb +13 -0
- data/app/views/loggable_activity/bootstrap/kaminari/_page.html.erb +14 -0
- data/app/views/loggable_activity/bootstrap/kaminari/_paginator.html.erb +27 -0
- data/app/views/loggable_activity/bootstrap/kaminari/_prev_page.html.erb +13 -0
- data/config/initializers/kaminari_config.rb +1 -1
- data/lib/generators/loggable_activity/install/install_generator.rb +68 -0
- data/lib/generators/loggable_activity/install/templates/create_loggable_activities.rb +45 -0
- data/lib/generators/loggable_activity/install/templates/loggable_activity.en.yml +32 -0
- data/lib/generators/loggable_activity/install/templates/loggable_activity.rb +27 -0
- data/lib/generators/loggable_activity/install/templates/loggable_activity.yml +103 -0
- data/lib/loggable_activity/activity.rb +4 -3
- data/lib/loggable_activity/config_schema.json +2 -20
- data/lib/loggable_activity/configuration.rb +0 -15
- data/lib/loggable_activity/encryption.rb +33 -12
- data/lib/loggable_activity/encryption_key.rb +1 -1
- data/lib/loggable_activity/engine.rb +0 -5
- data/lib/loggable_activity/error.rb +3 -3
- data/lib/loggable_activity/hooks.rb +42 -18
- data/lib/loggable_activity/payload.rb +6 -4
- data/lib/loggable_activity/services/base_payloads_builder.rb +2 -1
- data/lib/loggable_activity/services/custom_payloads_builder.rb +55 -0
- data/lib/loggable_activity/services/payloads_builder.rb +3 -3
- data/lib/loggable_activity/services/update_payloads_builder.rb +4 -4
- data/lib/loggable_activity/version.rb +1 -1
- data/lib/loggable_activity.rb +4 -1
- data/loggable_activity-0.5.0.gem +0 -0
- metadata +34 -127
- data/app/views/layouts/loggable_activity/application.html.erb +0 -19
- data/app/views/loggable_activity/activities/_activities.html.erb +0 -56
- data/app/views/loggable_activity/activities/show.html.erb +0 -2
- /data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_gap.html.erb +0 -0
- /data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_next_page.html.erb +0 -0
- /data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_page.html.erb +0 -0
- /data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_paginator.html.erb +0 -0
- /data/app/views/kaminari/{kaminari-turbo-bootstrap → pico}/_prev_page.html.erb +0 -0
- /data/app/views/{kaminari/kaminari-turbo-bootstrap → loggable_activity/bootstrap/kaminari}/_last_page.html.erb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8d0d096b34f0b29dc9d0af6fb1c44e7fb4ba79b85b92e0e6aee4d895e5dcc57
|
4
|
+
data.tar.gz: 35ffb9e0e97409e8da7d659a37a37a66e2305f441505c4852af03d9681b8d90d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2cae0fe288f7ac429004f9318e833af33d2b629b57041dfa6d2da11e81b6cf10cd282ee0672b5a8aab4a0529ff9637f682979c9b91749559827863b42281c10
|
7
|
+
data.tar.gz: 7f068e3bf66ac331a646e909c631d79ef9e455643f13b2ac9a3e574d99e9dfefc046d76885a6f38bba275a5763c8c7f64980076a86cbc4e230dd4d65aaa64d2c
|
data/.rubocop.yml
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
AllCops:
|
2
|
+
NewCops: enable
|
2
3
|
Exclude:
|
3
4
|
- 'db/migrate/20240702092648_create_loggable_activity_tables.rb'
|
4
5
|
Layout/LineLength:
|
@@ -9,6 +10,8 @@ Layout/LineLength:
|
|
9
10
|
Metrics/AbcSize:
|
10
11
|
Exclude:
|
11
12
|
- 'lib/loggable_activity/encryption.rb'
|
13
|
+
- 'lib/loggable_activity/services/update_payloads_builder.rb'
|
14
|
+
- 'lib/generators/loggable_activity/install/templates/create_loggable_activities.rb'
|
12
15
|
Metrics/BlockLength:
|
13
16
|
Exclude:
|
14
17
|
- 'test/dummy/config/environments/development.rb'
|
@@ -18,6 +21,7 @@ Metrics/ClassLength:
|
|
18
21
|
Exclude:
|
19
22
|
- 'lib/loggable_activity/services/update_payloads_builder.rb'
|
20
23
|
Metrics/MethodLength:
|
24
|
+
Enabled: true
|
21
25
|
Exclude:
|
22
26
|
- 'lib/loggable_activity/services/update_payloads_builder.rb'
|
23
27
|
- 'lib/loggable_activity/services/destroy_payloads_builder.rb'
|
@@ -27,6 +31,9 @@ Metrics/MethodLength:
|
|
27
31
|
- 'lib/loggable_activity/activity.rb'
|
28
32
|
- 'lib/loggable_activity/services/payloads_builder.rb'
|
29
33
|
- 'lib/loggable_activity/hooks.rb'
|
34
|
+
- 'test/dummy/db/migrate/20240629154538_create_users.rb'
|
35
|
+
- 'lib/loggable_activity/services/custom_payloads_builder.rb'
|
36
|
+
- 'lib/generators/loggable_activity/install/templates/create_loggable_activities.rb'
|
30
37
|
Metrics/ModuleLength:
|
31
38
|
Exclude:
|
32
39
|
- 'lib/loggable_activity/hooks.rb'
|
@@ -36,3 +43,6 @@ Style/Documentation:
|
|
36
43
|
- 'app/models/loggable_activity/application_record.rb'
|
37
44
|
- 'app/mailers/loggable_activity/application_mailer.rb'
|
38
45
|
- 'app/helpers/loggable_activity/application_helper.rb'
|
46
|
+
Metrics/CyclomaticComplexity:
|
47
|
+
Exclude:
|
48
|
+
- 'lib/loggable_activity/hooks.rb'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## [0.5.6] - 2024-07-18
|
2
|
+
- Documentation updated
|
3
|
+
- Generator updated
|
4
|
+
|
5
|
+
## [0.5.5] - 2024-07-16
|
6
|
+
- Custom attrs added
|
7
|
+
### Breaking change
|
8
|
+
- Configuration.yml changed
|
9
|
+
|
10
|
+
## [0.5.4] - 2024-03-21
|
11
|
+
- Styling with bootstrap css
|
12
|
+
|
13
|
+
## [0.5.2] - 2024-03-21
|
14
|
+
- Styling with pico css
|
15
|
+
- Public attrs added
|
1
16
|
|
2
17
|
## [0.2.0] - 2024-07-03
|
3
18
|
- Keys kan be kept until LoggableActivity::Sanitizer.run is called
|
data/GETTING-STARTED.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Getting started
|
2
|
+
This document should you getting started with `LoggableActivity`
|
3
|
+
|
4
|
+
## Prerequisite
|
5
|
+
1 A running Rails Application<br/>
|
6
|
+
2 An authorization system where a current user or similar is available.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
Add the loggable_activity gem to the Gemfile `gem 'loggable_activity', '~> 0.5.4` and then<br/>
|
10
|
+
```
|
11
|
+
$ bundle install
|
12
|
+
```
|
13
|
+
Then we have to generate some migrations and execute them<br/>
|
14
|
+
```
|
15
|
+
$ bin/rails generate loggable_activity:install
|
16
|
+
$ bin/rails db:migrate
|
17
|
+
```
|
18
|
+
|
19
|
+
## Add hoks to models
|
20
|
+
```
|
21
|
+
class User < ApplicationRecord
|
22
|
+
include LoggableActivity::Hooks
|
23
|
+
```
|
24
|
+
|
25
|
+
## Configuration
|
26
|
+
Update `config/initializers/loggable_activity.rb` documentation is in the file.
|
27
|
+
|
28
|
+
## loggable_activity.yaml
|
29
|
+
You have to update the configuration file installed inside the `config/loggable_activity.yaml`
|
30
|
+
This file defines how data are logged.
|
31
|
+
|
32
|
+
## Automatically log show from controllers
|
33
|
+
This assumes that there is a current_user. E.g provided by the Devise gem</br>
|
34
|
+
Add a this to the application_controller.rb if you want automatically log show
|
35
|
+
```
|
36
|
+
class ApplicationController < ActionController::Base
|
37
|
+
include LoggableActivity::CurrentUser
|
38
|
+
```
|
39
|
+
Otherwise you might create `app/controllers/concerns/current_user.rb` and alter it .
|
40
|
+
|
41
|
+
## Manually log show from controllers
|
42
|
+
If you want to log the show action you can add this to your controllers show method
|
43
|
+
```
|
44
|
+
def show
|
45
|
+
@user.log(:show)
|
46
|
+
```
|
47
|
+
|
48
|
+
## For developers and contributors
|
49
|
+
You can download and play around with a demo app
|
50
|
+
- 1 Download the project from [github](https://github.com/LoggableActivity/LoggableActivity)
|
51
|
+
- 1 Download the demo application from [github](https://github.com/LoggableActivity/LoggableActivityDemoApp)
|
52
|
+
- 2 Update the Gemfile in the demo project so it points to your localhost.
|
53
|
+
```
|
54
|
+
Gemfile
|
55
|
+
|
56
|
+
gem 'loggable_activity', '~> VERSION', path: '/PATH_TO_PROJECT/LoggableActivityEngine/LoggableActivityEngine'
|
57
|
+
# gem 'loggable_activity', '~> VERSION'
|
58
|
+
```
|
59
|
+
*VERSION is the version number found in the gemfile*<br/>
|
60
|
+
*PATH_TO_PROJECT* is where you have stored the project on your local drive
|
data/README.md
CHANGED
@@ -1,31 +1,42 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
1
|
+
# Loggable Activity 🌟
|
2
|
+
Super easy to use activity log with views out of the box
|
3
|
+
- Just add the gem and mount the engine and you have a cool looking activity log.
|
4
|
+
- Easy and simple to customize and configure
|
5
|
+
- All data are encrypted, and
|
6
|
+
|
7
|
+
### Important!
|
8
|
+
This project is under development and not ready for production. There might be breaking changes, so please consult the CHANGELOG.md
|
9
|
+
### What it is not
|
10
|
+
- An error logging system
|
11
|
+
- A paper trails system with rollback.
|
12
|
+
- A backup system
|
13
|
+
|
14
|
+
### Applications
|
15
|
+
Most organizations needs to keep a log of how users interact with data stored in the DB
|
16
|
+
- Finance
|
17
|
+
- Healthcare
|
18
|
+
- Sales and Support
|
19
|
+
|
20
|
+
*Super simplified example from the healthcare.*
|
21
|
+
- Each patient has a journal, that is updated on a regular basis.
|
22
|
+
- Supervisor needs to follow the journal, how was it updated, who read it, did it get deleted.
|
23
|
+
- Security personnel needs to know how the journal is handled, who did what when.
|
24
|
+
- Patients has the right to know how their journal is handled and that their data will be removed when required.
|
25
|
+
|
26
|
+
Beside the journal in the db, an activity log is kept so it is possible to track how the journal is used.<br/>
|
27
|
+
At some point in time the patients data from the DB and the activity log has to be removed according to GDPR.<br/>
|
28
|
+
|
29
|
+
### Getting started
|
30
|
+
please read the [GETTING-STARTED.md](https://github.com/LoggableActivity/LoggableActivity/blob/main/GETTING-STARTED.md) guide
|
31
|
+
|
32
|
+
### Contribute
|
33
|
+
👉 Join the Slack channel here: [LoggableActivity Slack Workspace](https://join.slack.com/t/loggableactivity/shared_invite/zt-2a3tvgv37-mGwjHJTrBXBH2srXFRRSXQ)
|
34
|
+
<br/>
|
35
|
+
👉 Want to play around with an online version: [Show Demo](https://loggableactivity-efe7b931c886.herokuapp.com/)
|
36
|
+
<br/>
|
37
|
+
We value each contribution and believe in the power of community. Looking forward to seeing you there!
|
38
|
+
|
39
|
+
|
40
|
+
### Test
|
41
|
+
We embrace the philosophy of black-box testing, where we focus on the input and output of the public interface without worrying about internal implementation details.<br/>
|
42
|
+
This approach aligns with the principle of testing behavior rather than implementation.
|
@@ -0,0 +1,25 @@
|
|
1
|
+
.activity {
|
2
|
+
--bs-alert-bg: transparent;
|
3
|
+
--bs-alert-padding-x: 1rem;
|
4
|
+
--bs-alert-padding-y: 0.5rem;
|
5
|
+
// --bs-alert-margin-bottom: 1rem;
|
6
|
+
--bs-alert-color: inherit;
|
7
|
+
--bs-alert-border-color: transparent;
|
8
|
+
--bs-alert-border: var(--bs-border-width) solid var(--bs-alert-border-color);
|
9
|
+
--bs-alert-border-radius: var(--bs-border-radius);
|
10
|
+
--bs-alert-link-color: inherit;
|
11
|
+
position: relative;
|
12
|
+
padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x);
|
13
|
+
margin-bottom: var(--bs-alert-margin-bottom);
|
14
|
+
color: var(--bs-alert-color);
|
15
|
+
background-color: var(--bs-alert-bg);
|
16
|
+
border: var(--bs-alert-border);
|
17
|
+
// border-radius: 0;
|
18
|
+
}
|
19
|
+
|
20
|
+
.activity-info {
|
21
|
+
--bs-alert-color: var(--bs-info-text-emphasis);
|
22
|
+
--bs-alert-bg: var(--bs-info-bg-subtle);
|
23
|
+
--bs-alert-border-color: var(--bs-info-border-subtle);
|
24
|
+
--bs-alert-link-color: var(--bs-info-text-emphasis);
|
25
|
+
}
|
@@ -8,7 +8,6 @@
|
|
8
8
|
-%>
|
9
9
|
<% unless current_page.first? %>
|
10
10
|
<li class="page-item">
|
11
|
-
<%# <%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :class => 'page-link', :remote => remote %>
|
12
11
|
<%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, class: 'page-link', data: { turbo: true } %>
|
13
12
|
</li>
|
14
13
|
<% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%# Link to the "Last" page
|
2
|
+
- available local variables
|
3
|
+
url: url to the last page
|
4
|
+
current_page: a page object for the currently displayed page
|
5
|
+
num_pages: total number of pages
|
6
|
+
per_page: number of items to fetch per page
|
7
|
+
remote: data-remote
|
8
|
+
-%>
|
9
|
+
<% unless current_page.last? %>
|
10
|
+
<%= link_to_unless current_page.last?, raw(t('views.pagination.last')), url, class: 'page-link', data: { turbo: true } %>
|
11
|
+
</li>
|
12
|
+
<% end %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
title Loggable activity
|
5
|
+
= csrf_meta_tags
|
6
|
+
= csp_meta_tag
|
7
|
+
= stylesheet_link_tag "loggable_activity/application", media: "all"
|
8
|
+
|
9
|
+
link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/themes/prism.min.css" rel="stylesheet"
|
10
|
+
script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/prism.min.js"
|
11
|
+
|
12
|
+
= stylesheet_link_tag 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css',
|
13
|
+
integrity: 'sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH',
|
14
|
+
crossorigin: 'anonymous'
|
15
|
+
|
16
|
+
body data-bs-theme="dark"
|
17
|
+
= yield
|
18
|
+
= javascript_include_tag 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js',
|
19
|
+
integrity: 'sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz',
|
20
|
+
crossorigin: 'anonymous'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
.row
|
3
|
+
.col-3
|
4
|
+
b.text-secondary = t('loggable_activity.activity.action')
|
5
|
+
.col-3
|
6
|
+
b.text-secondary = t('loggable_activity.activity.record')
|
7
|
+
.col-3
|
8
|
+
b.text-secondary = t('loggable_activity.activity.actor')
|
9
|
+
.col-3
|
10
|
+
b.text-secondary = t('loggable_activity.activity.created_at')
|
11
|
+
|
12
|
+
- @activities.each do |activity|
|
13
|
+
.activity.activity-info[type="button" data-bs-toggle="collapse" data-bs-target="#activity_#{activity.id}" aria-expanded="false" aria-controls="collapseExample"]
|
14
|
+
.row
|
15
|
+
.col-3
|
16
|
+
= activity_action(activity)
|
17
|
+
.col-3
|
18
|
+
= activity.record_display_name
|
19
|
+
.col-3
|
20
|
+
= activity.actor_display_name
|
21
|
+
.col-3
|
22
|
+
= l(activity.created_at, format: :long)
|
23
|
+
.collapse id="activity_#{activity.id}"
|
24
|
+
pre
|
25
|
+
code.language-json
|
26
|
+
= format_json_for_display(activity.attrs)
|
27
|
+
javascript:
|
28
|
+
Prism.highlightAll();
|
@@ -1,7 +1,6 @@
|
|
1
|
-
<
|
2
|
-
|
1
|
+
<div class="container">
|
2
|
+
<h1>Activities</h1>
|
3
|
+
<%= paginate @activities, views_prefix: "loggable_activity/bootstrap" %>
|
4
|
+
<%= render partial: "activities", activities: @activities %>
|
5
|
+
</div>
|
3
6
|
|
4
|
-
<%= paginate @activities, theme: 'kaminari-turbo-bootstrap' %>
|
5
|
-
|
6
|
-
|
7
|
-
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%# Link to the "First" page
|
2
|
+
- available local variables
|
3
|
+
url: url to the first page
|
4
|
+
current_page: a page object for the currently displayed page
|
5
|
+
num_pages: total number of pages
|
6
|
+
per_page: number of items to fetch per page
|
7
|
+
remote: data-remote
|
8
|
+
-%>
|
9
|
+
<% unless current_page.first? %>
|
10
|
+
<li class="page-item">
|
11
|
+
<%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, class: 'page-link', data: { turbo: true } %>
|
12
|
+
</li>
|
13
|
+
<% end %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<%# Non-link tag that stands for skipped pages...
|
2
|
+
- available local variables
|
3
|
+
current_page: a page object for the currently displayed page
|
4
|
+
num_pages: total number of pages
|
5
|
+
per_page: number of items to fetch per page
|
6
|
+
remote: data-remote
|
7
|
+
-%>
|
8
|
+
<li class="page-item disabled"><a href="#" onclick="return false;" class="page-link"><%= raw(t 'views.pagination.truncate') %></a></li>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%# Link to the "Next" page
|
2
|
+
- available local variables
|
3
|
+
url: url to the next page
|
4
|
+
current_page: a page object for the currently displayed page
|
5
|
+
num_pages: total number of pages
|
6
|
+
per_page: number of items to fetch per page
|
7
|
+
remote: data-remote
|
8
|
+
-%>
|
9
|
+
<% unless current_page.last? %>
|
10
|
+
<li class="page-item">
|
11
|
+
<%= link_to_unless current_page.last?, raw(t('views.pagination.next')), url, class: 'page-link', rel: 'next', data: { turbo: true }, remote: remote %>
|
12
|
+
</li>
|
13
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%# Link showing page number
|
2
|
+
- available local variables
|
3
|
+
page: a page object for "this" page
|
4
|
+
url: url to this page
|
5
|
+
current_page: a page object for the currently displayed page
|
6
|
+
num_pages: total number of pages
|
7
|
+
per_page: number of items to fetch per page
|
8
|
+
remote: data-remote
|
9
|
+
-%>
|
10
|
+
<li class="page-item<%= ' active' if page.current? %>">
|
11
|
+
<%#= link_to page, url, opts = {:remote => remote, :class => 'page-link', :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil} %>
|
12
|
+
<%= link_to page, url, class: 'page-link', rel: page.next? ? 'next' : page.prev? ? 'prev' : nil, data: { turbo: true }, remote: remote %>
|
13
|
+
|
14
|
+
</li>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<%# The container tag
|
2
|
+
- available local variables
|
3
|
+
current_page: a page object for the currently displayed page
|
4
|
+
num_pages: total number of pages
|
5
|
+
per_page: number of items to fetch per page
|
6
|
+
remote: data-remote
|
7
|
+
paginator: the paginator that renders the pagination tags inside
|
8
|
+
-%>
|
9
|
+
<%- pagination_class ||= '' %>
|
10
|
+
<%- nav_class ||= '' %>
|
11
|
+
<%= paginator.render do -%>
|
12
|
+
<nav class="<%= nav_class %>">
|
13
|
+
<ul class="pagination <%= pagination_class %>">
|
14
|
+
<%= first_page_tag unless current_page.first? %>
|
15
|
+
<%= prev_page_tag unless current_page.first? %>
|
16
|
+
<% each_page do |page| -%>
|
17
|
+
<% if page.left_outer? || page.right_outer? || page.inside_window? -%>
|
18
|
+
<%= page_tag page %>
|
19
|
+
<% elsif !page.was_truncated? -%>
|
20
|
+
<%= gap_tag %>
|
21
|
+
<% end -%>
|
22
|
+
<% end -%>
|
23
|
+
<%= next_page_tag unless current_page.last? %>
|
24
|
+
<%= last_page_tag unless current_page.last? %>
|
25
|
+
</ul>
|
26
|
+
</nav>
|
27
|
+
<% end -%>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%# Link to the "Previous" page
|
2
|
+
- available local variables
|
3
|
+
url: url to the previous page
|
4
|
+
current_page: a page object for the currently displayed page
|
5
|
+
num_pages: total number of pages
|
6
|
+
per_page: number of items to fetch per page
|
7
|
+
remote: data-remote
|
8
|
+
-%>
|
9
|
+
<% unless current_page.first? %>
|
10
|
+
<li class="page-item">
|
11
|
+
<%= link_to_unless current_page.first?, raw(t('views.pagination.previous')), url, rel: 'prev', class: 'page-link', data: { turbo: true }, remote: remote %>
|
12
|
+
</li>
|
13
|
+
<% end %>
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This module provides generators for installing and configuring LoggableActivity.
|
4
|
+
# It includes generators for creating initializer, migration, and locale files.
|
5
|
+
#
|
6
|
+
# Example usage:
|
7
|
+
# rails generate loggable_activity:install
|
8
|
+
#
|
9
|
+
# This will:
|
10
|
+
# - Create an initializer file in config/initializers/loggable_activity.rb
|
11
|
+
# - Create a migration file in db/migrate/
|
12
|
+
# - Create a locale file in config/locales/loggable_activity.en.yml
|
13
|
+
#
|
14
|
+
# After running the generator, remember to:
|
15
|
+
# - Add `mount LoggableActivity::Engine => '/loggable_activity'` to your routes.rb file.
|
16
|
+
# - Run `rails db:migrate` to create the necessary database tables.
|
17
|
+
# - Include `LoggableActivity::Hook` in the models you want to track.
|
18
|
+
# - Update the config/loggable_activity.yaml file with the fields you want to track.
|
19
|
+
# - Ensure the locale files are properly set up in config/locales/loggable_activity.en.yml.
|
20
|
+
module LoggableActivity
|
21
|
+
module Generators
|
22
|
+
# The InstallGenerator class is responsible for copying the necessary
|
23
|
+
# files to set up LoggableActivity in a Rails application.
|
24
|
+
class InstallGenerator < Rails::Generators::Base
|
25
|
+
source_root File.expand_path('templates', __dir__)
|
26
|
+
|
27
|
+
desc 'Creates a LoggableActivity initializer in your application.'
|
28
|
+
def copy_initializer
|
29
|
+
template 'loggable_activity.rb', 'config/initializers/loggable_activity.rb'
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'Creates a migration file for LoggableActivity in your application.'
|
33
|
+
def copy_migration
|
34
|
+
template 'create_loggable_activities.rb', "db/migrate/#{migration_number}_create_loggable_activities.rb"
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'Creates a locale file for LoggableActivity in your application.'
|
38
|
+
def copy_locale
|
39
|
+
template 'loggable_activity.en.yml', 'config/locales/loggable_activity.en.yml'
|
40
|
+
end
|
41
|
+
|
42
|
+
# Generates a timestamp to use in the migration filename.
|
43
|
+
#
|
44
|
+
# @return [String] the current UTC time formatted as a timestamp
|
45
|
+
def migration_number
|
46
|
+
Time.now.utc.strftime('%Y%m%d%H%M%S')
|
47
|
+
end
|
48
|
+
|
49
|
+
puts ''
|
50
|
+
puts "\e[1m\e[32m* ----------------------------- LoggableActivity ----------------------------- *\e[0m"
|
51
|
+
puts "\e[1m\e[32m* *\e[0m"
|
52
|
+
puts "\e[1m\e[32m* LoggableActivity has been successfully installed. *\e[0m"
|
53
|
+
puts "\e[1m\e[32m* Add the following to your routes.rb file. *\e[0m"
|
54
|
+
puts "\e[1m\e[32m* Mount LoggableActivity::Engine => '/loggable_activity' *\e[0m"
|
55
|
+
puts "\e[1m\e[32m* *\e[0m"
|
56
|
+
puts "\e[1m\e[32m* $ rails db:migrate to create the tables. *\e[0m"
|
57
|
+
puts "\e[1m\e[32m* *\e[0m"
|
58
|
+
puts "\e[1m\e[32m* Add include LoggableActivity::Hook to the models you want to track. *\e[0m"
|
59
|
+
puts "\e[1m\e[32m* *\e[0m"
|
60
|
+
puts "\e[1m\e[32m* Update the config/loggable_activity.yaml file with fields to track. *\e[0m"
|
61
|
+
puts "\e[1m\e[32m* *\e[0m"
|
62
|
+
puts "\e[1m\e[32m* Locale files are found in config/locale/loggable_activity.en.yaml. *\e[0m"
|
63
|
+
puts "\e[1m\e[32m* *\e[0m"
|
64
|
+
puts "\e[1m\e[32m* ---------------------------------------------------------------------------- *\e[0m"
|
65
|
+
puts ''
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This migration creates the necessary tables for LoggableActivity.
|
4
|
+
class CreateLoggableActivities < ActiveRecord::Migration[7.1]
|
5
|
+
def change
|
6
|
+
create_table :loggable_activity_encryption_keys do |t|
|
7
|
+
t.references :record, polymorphic: true, null: true, index: true
|
8
|
+
t.string :secret_key
|
9
|
+
t.datetime :delete_at
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
create_table :loggable_activity_activities do |t|
|
15
|
+
t.string :action
|
16
|
+
t.references :actor, polymorphic: true, null: true
|
17
|
+
t.string :encrypted_actor_name
|
18
|
+
t.references :record, polymorphic: true, null: true
|
19
|
+
|
20
|
+
t.timestamps
|
21
|
+
end
|
22
|
+
|
23
|
+
create_table :loggable_activity_payloads do |t|
|
24
|
+
t.references :activity, null: false, foreign_key: { to_table: 'loggable_activity_activities' }
|
25
|
+
t.references :encryption_key, null: false, foreign_key: { to_table: 'loggable_activity_encryption_keys' }
|
26
|
+
t.references :record, polymorphic: true, null: true, index: true
|
27
|
+
t.string :encrypted_record_name
|
28
|
+
t.json :encrypted_attrs
|
29
|
+
t.integer :related_to_activity_as, default: 0
|
30
|
+
t.boolean :data_owner, default: false
|
31
|
+
t.string :route
|
32
|
+
t.boolean :current_payload, default: true
|
33
|
+
t.json :public_attrs, default: {}
|
34
|
+
|
35
|
+
t.timestamps
|
36
|
+
end
|
37
|
+
|
38
|
+
create_table :loggable_activity_data_owners do |t|
|
39
|
+
t.references :record, polymorphic: true, null: true, index: true
|
40
|
+
t.references :encryption_key, null: false, foreign_key: { to_table: 'loggable_activity_encryption_keys' }
|
41
|
+
|
42
|
+
t.timestamps
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
# This file was generated when you installed Loggable Activity and is used for internationalization.
|
3
|
+
# When a model 'includes LoggableActivity::Hooks' tags for translations are generated.
|
4
|
+
# Example:
|
5
|
+
# class User < ApplicationRecord
|
6
|
+
# include LoggableActivity::Hooks
|
7
|
+
# end
|
8
|
+
# This will make the following tags for translations available:
|
9
|
+
# - loggable_activity.user.create
|
10
|
+
# - loggable_activity.user.show
|
11
|
+
# - loggable_activity.user.update
|
12
|
+
# - loggable_activity.user.destroy
|
13
|
+
# - loggable_activity.user.login
|
14
|
+
# - loggable_activity.user.logout
|
15
|
+
#
|
16
|
+
en:
|
17
|
+
loggable_activity:
|
18
|
+
activity:
|
19
|
+
actor: Actor
|
20
|
+
action: Action
|
21
|
+
record: Record
|
22
|
+
created_at: Created at
|
23
|
+
deleted: "*** DELETED ***"
|
24
|
+
user:
|
25
|
+
update: A user was updated
|
26
|
+
create: A user was created
|
27
|
+
show: "A user was shown"
|
28
|
+
destroy: A user was deleted
|
29
|
+
sign_up: A user signed up
|
30
|
+
login: A user logged in
|
31
|
+
logout: A user logged out
|
32
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This configuration file is for setting up the LoggableActivity gem in your Rails application.
|
4
|
+
|
5
|
+
# Specify the name of the model that represents the actor performing the activities.
|
6
|
+
# This should be a string that matches the class name of the model.
|
7
|
+
# Example: If your user model is named "User", set it to 'User'.
|
8
|
+
LoggableActivity.actor_model_name = 'User'
|
9
|
+
|
10
|
+
# Specify the attribute from which to fetch the actor's name.
|
11
|
+
# This should be eighter a string representing the attribute name of the actor model
|
12
|
+
# or a method that returns the actor's name.
|
13
|
+
# Example: If you want to use the user's email as their name, set it to 'email'.
|
14
|
+
LoggableActivity.fetch_actor_name_from = 'email'
|
15
|
+
|
16
|
+
# Specify the path to the configuration file for LoggableActivity.
|
17
|
+
# This file should be a YAML file that contains the necessary configuration for logging activities.
|
18
|
+
# The path is set relative to the Rails root directory.
|
19
|
+
# Example: The default configuration file path is 'config/loggable_activity.yaml'.
|
20
|
+
LoggableActivity.config_file_path = Rails.root.join('config/loggable_activity.yaml')
|
21
|
+
|
22
|
+
# Specify whether the sanitazion should be performed by a task or not
|
23
|
+
# If set to 'false' the sanitization is performed immediately.
|
24
|
+
# If set to 'true' the data is inaccessible, but can be restored.
|
25
|
+
# If set to 'true' you have to permanently delete
|
26
|
+
# the data by calling 'LoggableActivity::Sanitizer.run' from a task.
|
27
|
+
LoggableActivity.task_for_sanitization = false
|