ditty 0.7.2 → 0.8.0
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 +4 -4
- data/.rubocop.yml +4 -7
- data/.travis.yml +5 -5
- data/Gemfile.ci +2 -0
- data/Rakefile +4 -3
- data/Readme.md +24 -2
- data/ditty.gemspec +4 -3
- data/lib/ditty.rb +24 -0
- data/lib/ditty/cli.rb +6 -2
- data/lib/ditty/components/app.rb +10 -1
- data/lib/ditty/controllers/application.rb +72 -10
- data/lib/ditty/controllers/audit_logs.rb +1 -5
- data/lib/ditty/controllers/auth.rb +37 -17
- data/lib/ditty/controllers/component.rb +15 -5
- data/lib/ditty/controllers/main.rb +1 -5
- data/lib/ditty/controllers/roles.rb +2 -5
- data/lib/ditty/controllers/user_login_traits.rb +18 -0
- data/lib/ditty/controllers/users.rb +4 -9
- data/lib/ditty/db.rb +3 -1
- data/lib/ditty/emails/base.rb +13 -4
- data/lib/ditty/helpers/authentication.rb +6 -5
- data/lib/ditty/helpers/component.rb +9 -1
- data/lib/ditty/helpers/response.rb +24 -3
- data/lib/ditty/helpers/views.rb +20 -0
- data/lib/ditty/listener.rb +38 -10
- data/lib/ditty/middleware/accept_extension.rb +2 -0
- data/lib/ditty/middleware/error_catchall.rb +2 -0
- data/lib/ditty/models/audit_log.rb +1 -0
- data/lib/ditty/models/base.rb +4 -0
- data/lib/ditty/models/identity.rb +3 -0
- data/lib/ditty/models/role.rb +1 -0
- data/lib/ditty/models/user.rb +9 -1
- data/lib/ditty/models/user_login_trait.rb +17 -0
- data/lib/ditty/policies/audit_log_policy.rb +6 -6
- data/lib/ditty/policies/role_policy.rb +2 -2
- data/lib/ditty/policies/user_login_trait_policy.rb +45 -0
- data/lib/ditty/policies/user_policy.rb +2 -2
- data/lib/ditty/rubocop.rb +3 -0
- data/lib/ditty/seed.rb +2 -0
- data/lib/ditty/services/authentication.rb +7 -2
- data/lib/ditty/services/email.rb +8 -2
- data/lib/ditty/services/logger.rb +11 -0
- data/lib/ditty/services/pagination_wrapper.rb +2 -0
- data/lib/ditty/services/settings.rb +14 -3
- data/lib/ditty/tasks/ditty.rake +109 -0
- data/lib/ditty/tasks/omniauth-ldap.rake +43 -0
- data/lib/ditty/version.rb +1 -1
- data/lib/rubocop/cop/ditty/call_services_directly.rb +42 -0
- data/migrate/20181209_add_user_login_traits.rb +16 -0
- data/migrate/20181209_extend_audit_log.rb +12 -0
- data/views/403.haml +2 -0
- data/views/audit_logs/index.haml +11 -6
- data/views/auth/ldap.haml +17 -0
- data/views/emails/forgot_password.haml +1 -1
- data/views/emails/layouts/action.haml +10 -6
- data/views/emails/layouts/alert.haml +2 -1
- data/views/emails/layouts/billing.haml +2 -1
- data/views/error.haml +8 -3
- data/views/partials/form_control.haml +24 -20
- data/views/partials/navbar.haml +11 -12
- data/views/partials/sidebar.haml +1 -1
- data/views/roles/index.haml +2 -0
- data/views/user_login_traits/display.haml +32 -0
- data/views/user_login_traits/edit.haml +10 -0
- data/views/user_login_traits/form.haml +5 -0
- data/views/user_login_traits/index.haml +30 -0
- data/views/user_login_traits/new.haml +10 -0
- data/views/users/display.haml +1 -1
- data/views/users/login_traits.haml +27 -0
- data/views/users/profile.haml +2 -0
- metadata +50 -21
- data/lib/ditty/rake_tasks.rb +0 -102
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b391296636a3f248171d3d71ca4c11466b8cce56f8814c271f2352e241da297
|
4
|
+
data.tar.gz: 8b136a384187ea59d6d8caa8f46f3dcc7a4a72939ba924ddff0eb8a332828aa1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8102d97c1b3516e4f922600055a22b5bff5293dd69fbcb92a5cd233ad0e9f2e52fc6f091e05aebcee9e1dd610e76b0049db29b1eccfd54ff09f794325156cf68
|
7
|
+
data.tar.gz: c1ad5e59438e58fc6dbc34d5d2a95b1c5da4a0ccb88481fc15b9dd5942ece2d7525adcf52d3d520f9fd2c91dff65829d24a27ad8fb60d66889ac6f9b983c2fba
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
- 2.
|
5
|
-
- 2.
|
6
|
-
- 2.
|
7
|
-
- 2.
|
4
|
+
- 2.6.0
|
5
|
+
- 2.5.3
|
6
|
+
- 2.4.5
|
7
|
+
- 2.3.8
|
8
8
|
gemfile: Gemfile.ci
|
9
9
|
env:
|
10
10
|
global:
|
@@ -21,7 +21,7 @@ before_script:
|
|
21
21
|
- bundle exec rake ditty:prep
|
22
22
|
script:
|
23
23
|
- bundle exec rake
|
24
|
-
- bundle exec rubocop --fail-level W lib views
|
24
|
+
- bundle exec rubocop --fail-level W lib views specs
|
25
25
|
after_script:
|
26
26
|
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
27
27
|
after_success:
|
data/Gemfile.ci
CHANGED
data/Rakefile
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rake'
|
4
|
-
require 'bundler/gem_tasks'
|
5
|
-
require 'ditty/rake_tasks'
|
6
|
-
|
7
4
|
require 'ditty'
|
8
5
|
require 'ditty/components/app'
|
9
6
|
|
7
|
+
Ditty.component :app
|
8
|
+
|
9
|
+
Ditty::Components.tasks
|
10
|
+
require 'bundler/gem_tasks' if File.exist? 'ditty.gemspec'
|
10
11
|
begin
|
11
12
|
require 'rspec/core/rake_task'
|
12
13
|
RSpec::Core::RakeTask.new(:spec)
|
data/Readme.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[](https://travis-ci.org/EagerELK/ditty)
|
2
2
|
[](https://codeclimate.com/github/EagerELK/ditty)
|
3
3
|
[](https://codeclimate.com/github/EagerELK/ditty/coverage)
|
4
|
+
[](http://inch-ci.org/github/EagerELK/ditty)
|
4
5
|
|
5
6
|
# Ditty
|
6
7
|
|
@@ -33,12 +34,33 @@ gem install ditty
|
|
33
34
|
|
34
35
|
1. Add the components to your rack config file. See the included [`config.ru`](https://github.com/EagerELK/ditty/blob/master/config.ru) file for an example setup
|
35
36
|
2. Set the DB connection as the `DATABASE_URL` ENV variable: `DATABASE_URL=sqlite://development.db`
|
37
|
+
3. Prepare the Ditty folder: `bundle exec ditty prep`
|
36
38
|
3. Run the Ditty migrations: `bundle exec ditty migrate`
|
37
39
|
4. Run the Ditty server: `bundle exec ditty server`
|
38
40
|
|
39
|
-
|
41
|
+
### Components
|
40
42
|
|
41
|
-
The application can now be further extended by creating components.
|
43
|
+
The application can now be further extended by creating [components](https://github.com/EagerELK/ditty/wiki/Creating-a-Component).
|
44
|
+
|
45
|
+
### Rubocop Cops
|
46
|
+
|
47
|
+
Ditty provides a number of [Rubocop](https://github.com/rubocop-hq/rubocop) cops
|
48
|
+
to ensure that the Ditty framework is used correctly. Enable this by adding the
|
49
|
+
following to your `.rubocop.yml` file:
|
50
|
+
|
51
|
+
```yaml
|
52
|
+
require: ditty/rubocop
|
53
|
+
```
|
54
|
+
|
55
|
+
You can run Ditty specific cops as follows:
|
56
|
+
|
57
|
+
```bash
|
58
|
+
bundle exec rubocop --only Ditty
|
59
|
+
```
|
60
|
+
|
61
|
+
Adding the `-a` flag to the invocation will automatically fix some of the issues
|
62
|
+
for you, but, as always, ensure you have a working copy of your code before
|
63
|
+
running this.
|
42
64
|
|
43
65
|
## Development
|
44
66
|
|
data/ditty.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = ['ditty']
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.add_development_dependency 'bundler', '
|
23
|
+
spec.add_development_dependency 'bundler', '>= 1'
|
24
24
|
spec.add_development_dependency 'database_cleaner'
|
25
25
|
spec.add_development_dependency 'factory_bot'
|
26
26
|
spec.add_development_dependency 'rack-test'
|
@@ -30,10 +30,11 @@ Gem::Specification.new do |spec|
|
|
30
30
|
|
31
31
|
spec.add_dependency 'activesupport', '>= 3'
|
32
32
|
spec.add_dependency 'bcrypt', '~> 3.1'
|
33
|
+
spec.add_dependency 'browser', '~> 2.5'
|
33
34
|
spec.add_dependency 'haml', '~> 5.0'
|
34
35
|
spec.add_dependency 'logger', '~> 1.0'
|
35
|
-
spec.add_dependency 'oga', '>= 2.14'
|
36
36
|
spec.add_dependency 'mail', '>= 1.7'
|
37
|
+
spec.add_dependency 'oga', '>= 2.14'
|
37
38
|
spec.add_dependency 'omniauth', '~> 1.0'
|
38
39
|
spec.add_dependency 'omniauth-identity', '~> 1.0'
|
39
40
|
spec.add_dependency 'pundit', '~> 1.0'
|
@@ -45,8 +46,8 @@ Gem::Specification.new do |spec|
|
|
45
46
|
spec.add_dependency 'sinatra-contrib', '~> 2.0'
|
46
47
|
spec.add_dependency 'sinatra-flash', '~> 0.3'
|
47
48
|
spec.add_dependency 'sinatra-param', '~> 1.5'
|
48
|
-
spec.add_dependency 'tilt', '>= 2'
|
49
49
|
spec.add_dependency 'thor', '>= 0.20'
|
50
|
+
spec.add_dependency 'tilt', '>= 2'
|
50
51
|
spec.add_dependency 'will_paginate', '>= 3.1'
|
51
52
|
spec.add_dependency 'wisper', '~> 2.0'
|
52
53
|
end
|
data/lib/ditty.rb
CHANGED
@@ -6,6 +6,8 @@ require 'ditty/services/logger'
|
|
6
6
|
module Ditty
|
7
7
|
class ComponentError < StandardError; end
|
8
8
|
|
9
|
+
class TemplateNotFoundError < StandardError; end
|
10
|
+
|
9
11
|
# A thread safe cache class, offering only #[] and #[]= methods,
|
10
12
|
# each protected by a mutex.
|
11
13
|
# Ripped off from Roda - https://github.com/jeremyevans/roda
|
@@ -30,6 +32,10 @@ module Ditty
|
|
30
32
|
@mutex.synchronize { @hash.map(&block) }
|
31
33
|
end
|
32
34
|
|
35
|
+
def each(&block)
|
36
|
+
@mutex.synchronize { @hash.each(&block) }
|
37
|
+
end
|
38
|
+
|
33
39
|
def inject(memo, &block)
|
34
40
|
@mutex.synchronize { @hash.inject(memo, &block) }
|
35
41
|
end
|
@@ -37,6 +43,10 @@ module Ditty
|
|
37
43
|
def each_with_object(memo, &block)
|
38
44
|
@mutex.synchronize { @hash.each_with_object(memo, &block) }
|
39
45
|
end
|
46
|
+
|
47
|
+
def key?(key)
|
48
|
+
@hash.key? key
|
49
|
+
end
|
40
50
|
end
|
41
51
|
|
42
52
|
# Ripped off from Roda - https://github.com/jeremyevans/roda
|
@@ -57,6 +67,10 @@ module Ditty
|
|
57
67
|
component
|
58
68
|
end
|
59
69
|
|
70
|
+
def self.component?(name)
|
71
|
+
@components.key? name
|
72
|
+
end
|
73
|
+
|
60
74
|
# Register the given component with Component, so that it can be loaded using #component
|
61
75
|
# with a symbol. Should be used by component files. Example:
|
62
76
|
#
|
@@ -111,6 +125,15 @@ module Ditty
|
|
111
125
|
end
|
112
126
|
end
|
113
127
|
|
128
|
+
def self.tasks
|
129
|
+
require 'rake'
|
130
|
+
require 'rake/tasklib'
|
131
|
+
require 'ditty/db' unless defined? DB
|
132
|
+
components.each do |_name, comp|
|
133
|
+
comp.tasks if comp.respond_to?(:tasks)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
114
137
|
module Base
|
115
138
|
module ClassMethods
|
116
139
|
# Load a new component into the current class. A component can be a module
|
@@ -121,6 +144,7 @@ module Ditty
|
|
121
144
|
# Component.component :csrf
|
122
145
|
def component(component, *args, &block)
|
123
146
|
raise ComponentError, 'Cannot add a component to a frozen Component class' if frozen?
|
147
|
+
|
124
148
|
component = Components.load_component(component) if component.is_a?(Symbol)
|
125
149
|
include(component::InstanceMethods) if defined?(component::InstanceMethods)
|
126
150
|
extend(component::ClassMethods) if defined?(component::ClassMethods)
|
data/lib/ditty/cli.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# https://nandovieira.com/creating-generators-and-executables-with-thor
|
2
4
|
require 'dotenv/load'
|
3
5
|
require 'thor'
|
4
|
-
require 'ditty'
|
5
|
-
require 'ditty/rake_tasks'
|
6
6
|
require 'rack'
|
7
7
|
require 'rake'
|
8
8
|
|
@@ -12,6 +12,7 @@ module Ditty
|
|
12
12
|
|
13
13
|
desc 'server', 'Start the Ditty server'
|
14
14
|
require './application' if File.exist?('application.rb')
|
15
|
+
Ditty::Components.tasks
|
15
16
|
def server
|
16
17
|
# Ensure the token files are present
|
17
18
|
Rake::Task['ditty:generate_tokens'].invoke
|
@@ -39,6 +40,9 @@ module Ditty
|
|
39
40
|
# Run the migrations
|
40
41
|
Rake::Task['ditty:migrate:up'].invoke
|
41
42
|
puts 'Ditty Migrations Executed'
|
43
|
+
|
44
|
+
Rake::Task['ditty:dump_schema'].invoke
|
45
|
+
puts 'Ditty DB Schema Dumped'
|
42
46
|
end
|
43
47
|
end
|
44
48
|
end
|
data/lib/ditty/components/app.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'ditty'
|
4
|
+
require 'ditty/services/settings'
|
4
5
|
|
5
6
|
module Ditty
|
6
7
|
class App
|
@@ -12,6 +13,7 @@ module Ditty
|
|
12
13
|
require 'ditty/models/role'
|
13
14
|
require 'ditty/models/identity'
|
14
15
|
require 'ditty/models/audit_log'
|
16
|
+
require 'ditty/models/user_login_trait'
|
15
17
|
end
|
16
18
|
|
17
19
|
def self.configure(_container)
|
@@ -34,7 +36,8 @@ module Ditty
|
|
34
36
|
'/auth' => ::Ditty::Auth,
|
35
37
|
'/users' => ::Ditty::Users,
|
36
38
|
'/roles' => ::Ditty::Roles,
|
37
|
-
'/audit-logs' => ::Ditty::AuditLogs
|
39
|
+
'/audit-logs' => ::Ditty::AuditLogs,
|
40
|
+
'/login-traits' => ::Ditty::UserLoginTraits
|
38
41
|
}
|
39
42
|
end
|
40
43
|
|
@@ -65,6 +68,12 @@ module Ditty
|
|
65
68
|
::Ditty::Role.find_or_create(name: 'user')
|
66
69
|
end
|
67
70
|
end
|
71
|
+
|
72
|
+
def self.tasks
|
73
|
+
Kernel.load 'ditty/tasks/ditty.rake'
|
74
|
+
auth_settings = Ditty::Services::Settings[:authentication] || {}
|
75
|
+
Kernel.load 'ditty/tasks/omniauth-ldap.rake' if auth_settings.key?(:ldap)
|
76
|
+
end
|
68
77
|
end
|
69
78
|
end
|
70
79
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'browser/browser'
|
3
4
|
require 'wisper'
|
4
5
|
require 'oga'
|
5
6
|
require 'sinatra/base'
|
@@ -22,6 +23,7 @@ module Ditty
|
|
22
23
|
set :root, ENV['APP_ROOT'] || ::File.expand_path(::File.dirname(__FILE__) + '/../../../')
|
23
24
|
set :map_path, nil
|
24
25
|
set :view_location, nil
|
26
|
+
set :view_folder, nil
|
25
27
|
set :model_class, nil
|
26
28
|
set :raise_sinatra_param_exceptions, true
|
27
29
|
set track_actions: false
|
@@ -39,6 +41,10 @@ module Ditty
|
|
39
41
|
use Rack::NestedParams
|
40
42
|
|
41
43
|
helpers do
|
44
|
+
def logger
|
45
|
+
Ditty::Services::Logger.instance
|
46
|
+
end
|
47
|
+
|
42
48
|
def base_path
|
43
49
|
settings.base_path || "#{settings.map_path}/#{dasherize(view_location)}"
|
44
50
|
end
|
@@ -46,8 +52,33 @@ module Ditty
|
|
46
52
|
def view_location
|
47
53
|
return settings.view_location if settings.view_location
|
48
54
|
return underscore(pluralize(demodulize(settings.model_class))) if settings.model_class
|
55
|
+
|
49
56
|
underscore(demodulize(self.class))
|
50
57
|
end
|
58
|
+
|
59
|
+
def browser
|
60
|
+
Browser.new(request.user_agent, accept_language: request.env['HTTP_ACCEPT_LANGUAGE'])
|
61
|
+
end
|
62
|
+
|
63
|
+
def config(name, default = '')
|
64
|
+
Ditty::Services::Settings[name] || default
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def view_folders
|
69
|
+
folders = ['./views']
|
70
|
+
folders << settings.view_folder if settings.view_folder
|
71
|
+
folders << Ditty::App.view_folder
|
72
|
+
end
|
73
|
+
|
74
|
+
def find_template(views, name, engine, &block)
|
75
|
+
# Backwards compatability
|
76
|
+
return super(views, name, engine, &block) if settings.view_folder.nil? && self.class.name.split('::').first != 'Ditty'
|
77
|
+
|
78
|
+
view_folders.each do |folder|
|
79
|
+
super(folder, name, engine, &block) # Root
|
80
|
+
end
|
81
|
+
raise Ditty::TemplateNotFoundError, "Could not find template `#{name}`"
|
51
82
|
end
|
52
83
|
|
53
84
|
configure :production do
|
@@ -77,14 +108,28 @@ module Ditty
|
|
77
108
|
end
|
78
109
|
|
79
110
|
error Helpers::NotAuthenticated, ::Pundit::NotAuthorizedError do
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
111
|
+
# TODO: Check if this is logged / tracked
|
112
|
+
if authenticated?
|
113
|
+
respond_to do |format|
|
114
|
+
status 403
|
115
|
+
format.html do
|
116
|
+
flash.now[:danger] = 'Cannot perform that action at the moment.'
|
117
|
+
haml :'403', locals: { title: 'Forbidden' }, layout: layout
|
118
|
+
end
|
119
|
+
format.json do
|
120
|
+
json code: 403, errors: ['Forbidden']
|
121
|
+
end
|
85
122
|
end
|
86
|
-
|
87
|
-
|
123
|
+
else
|
124
|
+
respond_to do |format|
|
125
|
+
format.html do
|
126
|
+
flash[:warning] = 'Please log in first.'
|
127
|
+
redirect with_layout("#{settings.map_path}/auth/login")
|
128
|
+
end
|
129
|
+
format.json do
|
130
|
+
status 401
|
131
|
+
json code: 401, errors: ['Not Authenticated']
|
132
|
+
end
|
88
133
|
end
|
89
134
|
end
|
90
135
|
end
|
@@ -120,7 +165,7 @@ module Ditty
|
|
120
165
|
error ::Sequel::ForeignKeyConstraintViolation do
|
121
166
|
error = env['sinatra.error']
|
122
167
|
broadcast(:application_error, error)
|
123
|
-
|
168
|
+
logger.error error
|
124
169
|
respond_to do |format|
|
125
170
|
status 400
|
126
171
|
format.html do
|
@@ -132,10 +177,23 @@ module Ditty
|
|
132
177
|
end
|
133
178
|
end
|
134
179
|
|
180
|
+
error Ditty::TemplateNotFoundError do
|
181
|
+
# TODO: Display a better error message
|
182
|
+
error = env['sinatra.error']
|
183
|
+
broadcast(:application_error, error)
|
184
|
+
logger.error error
|
185
|
+
respond_to do |format|
|
186
|
+
status 500
|
187
|
+
format.html do
|
188
|
+
haml :error, locals: { title: 'Template not found', error: error }, layout: layout
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
135
193
|
error do
|
136
194
|
error = env['sinatra.error']
|
137
195
|
broadcast(:application_error, error)
|
138
|
-
|
196
|
+
logger.error error
|
139
197
|
respond_to do |format|
|
140
198
|
status 500
|
141
199
|
format.html do
|
@@ -148,10 +206,13 @@ module Ditty
|
|
148
206
|
end
|
149
207
|
|
150
208
|
before(/.*/) do
|
151
|
-
|
209
|
+
logger.info "Running with #{self.class} - #{request.path_info}"
|
152
210
|
if request.path =~ /.*\.json\Z/
|
153
211
|
content_type :json
|
154
212
|
request.path_info = request.path_info.gsub(/.json$/, '')
|
213
|
+
elsif request.path =~ /.*\.csv\Z/
|
214
|
+
content_type :csv
|
215
|
+
request.path_info = request.path_info.gsub(/.csv$/, '')
|
155
216
|
elsif request.env['ACCEPT']
|
156
217
|
content_type request.env['ACCEPT']
|
157
218
|
else
|
@@ -161,6 +222,7 @@ module Ditty
|
|
161
222
|
|
162
223
|
after do
|
163
224
|
return if params[:layout].nil?
|
225
|
+
|
164
226
|
response.body = response.body.map do |resp|
|
165
227
|
document = Oga.parse_html(resp)
|
166
228
|
document.css('a').each do |elm|
|
@@ -8,6 +8,7 @@ module Ditty
|
|
8
8
|
class AuditLogs < Ditty::Component
|
9
9
|
set model_class: AuditLog
|
10
10
|
|
11
|
+
SEARCHABLE = %i[details platform device browser ip_address].freeze
|
11
12
|
FILTERS = [
|
12
13
|
{ name: :user, field: 'user.email' },
|
13
14
|
{ name: :action }
|
@@ -23,11 +24,6 @@ module Ditty
|
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
26
|
-
def find_template(views, name, engine, &block)
|
27
|
-
super(views, name, engine, &block) # Root
|
28
|
-
super(::Ditty::App.view_folder, name, engine, &block) # Ditty
|
29
|
-
end
|
30
|
-
|
31
27
|
def list
|
32
28
|
super.order(:created_at).reverse
|
33
29
|
end
|