carload 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +125 -0
- data/Rakefile +37 -0
- data/app/assets/config/carload_manifest.js +2 -0
- data/app/assets/javascripts/carload/application.js +5 -0
- data/app/assets/javascripts/carload/dashboard.js +12 -0
- data/app/assets/stylesheets/carload/_select2.scss +13 -0
- data/app/assets/stylesheets/carload/application.scss +25 -0
- data/app/assets/stylesheets/carload/colors.scss +2 -0
- data/app/assets/stylesheets/carload/common.scss +77 -0
- data/app/assets/stylesheets/carload/dashboard.scss +82 -0
- data/app/assets/stylesheets/carload/error.scss +4 -0
- data/app/controllers/carload/application_controller.rb +21 -0
- data/app/controllers/carload/dashboard_controller.rb +85 -0
- data/app/controllers/carload/errors_controller.rb +21 -0
- data/app/helpers/carload/application_helper.rb +4 -0
- data/app/helpers/carload/dashboard_helper.rb +30 -0
- data/app/jobs/carload/application_job.rb +4 -0
- data/app/mailers/carload/application_mailer.rb +6 -0
- data/app/models/carload/application_record.rb +5 -0
- data/app/policies/application_policy.rb +53 -0
- data/app/policies/dashboard_policy.rb +21 -0
- data/app/views/carload/dashboard/_form.html.erb +7 -0
- data/app/views/carload/dashboard/edit.html.erb +12 -0
- data/app/views/carload/dashboard/index.html.erb +46 -0
- data/app/views/carload/dashboard/new.html.erb +12 -0
- data/app/views/carload/dashboard/shared/_index_buttons.html.erb +3 -0
- data/app/views/carload/dashboard/shared/_search_fields.html.erb +11 -0
- data/app/views/carload/errors/dashboard_error.html.erb +8 -0
- data/app/views/carload/errors/unauthorized_error.html.erb +8 -0
- data/app/views/kaminari/_first_page.html.erb +3 -0
- data/app/views/kaminari/_gap.html.erb +3 -0
- data/app/views/kaminari/_last_page.html.erb +3 -0
- data/app/views/kaminari/_next_page.html.erb +3 -0
- data/app/views/kaminari/_page.html.erb +9 -0
- data/app/views/kaminari/_paginator.html.erb +15 -0
- data/app/views/kaminari/_prev_page.html.erb +3 -0
- data/app/views/layouts/carload/application.html.erb +20 -0
- data/app/views/layouts/carload/dashboard.html.erb +32 -0
- data/config/initializers/assets.rb +1 -0
- data/config/initializers/simple_form.rb +165 -0
- data/config/initializers/simple_form_bootstrap.rb +149 -0
- data/config/locales/en.yml +37 -0
- data/config/locales/simple_form.en.yml +31 -0
- data/config/locales/zh-CN.yml +37 -0
- data/config/routes.rb +16 -0
- data/lib/carload/dashboard.rb +47 -0
- data/lib/carload/engine.rb +12 -0
- data/lib/carload/exceptions.rb +17 -0
- data/lib/carload/extended_hash.rb +12 -0
- data/lib/carload/version.rb +3 -0
- data/lib/carload.rb +27 -0
- data/lib/generators/carload/USAGE +15 -0
- data/lib/generators/carload/install_generator.rb +30 -0
- data/lib/generators/carload/templates/carload.rb +18 -0
- data/lib/generators/carload/templates/dashboard.rb +19 -0
- data/lib/tasks/carload_tasks.rake +4 -0
- data/lib/templates/erb/scaffold/_form.html.erb +13 -0
- metadata +277 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8f8cf9b142c5e13784ccffe393d2d9645655887f
|
4
|
+
data.tar.gz: 0aa2c2d084dd387f84f40e6f6aae4019257e7fe2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a7850af28727246a420c16a7cda6bc024b46c22350784e4f7197c0e1801ad8b0cb3c14b4480e7163d7f86d8ca53d6406cd1a80180bd5e9f88d445f3e3df5534d
|
7
|
+
data.tar.gz: e1198767a2f476a07434960bec5c83386eb88f69f31d489ed06690accace7da7413494145dc06067054ff0910e804fd1b243b76695fdacb09323195120772949
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2016 Li Dong
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
# Carload
|
2
|
+
This is another dashboard gem for Rails (see [Rails Admin], [ActiveAdmin] and [Administrate]). Carload tries to reduce the typing when implement a dashboard, but it also allow developer to realize any page view if they like.
|
3
|
+
|
4
|
+
[Rails Admin]: https://github.com/sferik/rails_admin
|
5
|
+
[ActiveAdmin]: http://activeadmin.info/
|
6
|
+
[Administrate]: https://github.com/thoughtbot/administrate
|
7
|
+
|
8
|
+
DEMO: [https://carload-demo.herokuapp.com/carload/dashboard/](https://carload-demo.herokuapp.com/carload/dashboard/)
|
9
|
+
|
10
|
+

|
11
|
+
|
12
|
+
## Usage
|
13
|
+
- Run `rails g carload:install` to mount engine routes, add require statement and add initializer.
|
14
|
+
|
15
|
+
You can edit the initializer `config/initializers/carload.rb` for example:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
Carload.setup do |config|
|
19
|
+
# Specify which authentication solution is used. Currently, we only support Devise.
|
20
|
+
config.auth_solution = :devise
|
21
|
+
|
22
|
+
# Set the actions used to discern user's permission to access dashboard.
|
23
|
+
#
|
24
|
+
# config.dashboard.permits_user.<method> = '...'
|
25
|
+
#
|
26
|
+
# There are four access methods can be configured:
|
27
|
+
#
|
28
|
+
# index, new, edit, destroy
|
29
|
+
#
|
30
|
+
# Also you can use a special method 'all' to set the default permission.
|
31
|
+
# The permission can also be array, the relation among them is OR.
|
32
|
+
# By doing this, you have full control on the access permission.
|
33
|
+
# TODO: Set the permissions for each data table.
|
34
|
+
config.dashboard.permits_user.all = 'role.admin?'
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
- Run `rails g carload:dashboard` to generate `app/carload/dashboard.rb`, and edit that file for example:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
# Dashboard class is used to tell Carload what models are needed to administrated,
|
42
|
+
# which attributes are shown, etc.
|
43
|
+
|
44
|
+
class Dashboard < Carload::Dashboard
|
45
|
+
# There are two DSL block types:
|
46
|
+
#
|
47
|
+
# model :<model_name> do |spec|
|
48
|
+
# # Whether model should be displayed when URL does not specify one
|
49
|
+
# spec.default = <true_or_false>
|
50
|
+
# # List of attributes that can be edited
|
51
|
+
# spec.attributes.permitted = [...]
|
52
|
+
# # List of attributes that will be shown on index page
|
53
|
+
# spec.index_page.shows.attributes = [...]
|
54
|
+
# # List of attributes with search terms that can be searched on index page (using Ransack gem)
|
55
|
+
# spec.index_page.searches.attributes = [ { name: ..., term: ...}, ... ]
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# associate :<model_name_a> => :<model_name_b>, choose_by: :<attribute_in_model_b>
|
59
|
+
|
60
|
+
model :product do |spec|
|
61
|
+
spec.default = true
|
62
|
+
spec.attributes.permitted = [ :name ]
|
63
|
+
spec.index_page.shows.attributes = [ :name ]
|
64
|
+
spec.index_page.searches.attributes = [
|
65
|
+
{ name: :name, term: :cont }
|
66
|
+
]
|
67
|
+
end
|
68
|
+
model :item do |spec|
|
69
|
+
spec.attributes.permitted = [ :name, :product_id ]
|
70
|
+
spec.index_page.shows.attributes = [ :name, 'product.name' ]
|
71
|
+
spec.index_page.searches.attributes = [
|
72
|
+
{ name: :name, term: :cont },
|
73
|
+
{ name: 'product.name', term: :cont }
|
74
|
+
]
|
75
|
+
end
|
76
|
+
associate :item => :product, choose_by: :name
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
- Make sure you have the necessary I18n translation files, for example:
|
81
|
+
|
82
|
+
```yaml
|
83
|
+
en:
|
84
|
+
activerecord:
|
85
|
+
models:
|
86
|
+
item: Item
|
87
|
+
attributes:
|
88
|
+
item:
|
89
|
+
name: Name
|
90
|
+
product:
|
91
|
+
name: Product Name
|
92
|
+
```
|
93
|
+
```yaml
|
94
|
+
en:
|
95
|
+
activerecord:
|
96
|
+
models:
|
97
|
+
product: Product
|
98
|
+
attributes:
|
99
|
+
product:
|
100
|
+
name: Name
|
101
|
+
```
|
102
|
+
- Access the brand new dashboard in '<Your URL>/carload'.
|
103
|
+
|
104
|
+
## Installation
|
105
|
+
Add this line to your application's Gemfile:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
gem 'carload'
|
109
|
+
```
|
110
|
+
|
111
|
+
And then execute:
|
112
|
+
```bash
|
113
|
+
$ bundle
|
114
|
+
```
|
115
|
+
|
116
|
+
Or install it yourself as:
|
117
|
+
```bash
|
118
|
+
$ gem install carload
|
119
|
+
```
|
120
|
+
|
121
|
+
## Contributing
|
122
|
+
Contribution directions go here.
|
123
|
+
|
124
|
+
## License
|
125
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Carload'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
require 'bundler/gem_tasks'
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'lib'
|
31
|
+
t.libs << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
task default: :test
|
@@ -0,0 +1,12 @@
|
|
1
|
+
//= require jquery
|
2
|
+
//= require jquery_ujs
|
3
|
+
//= require turbolinks
|
4
|
+
//= require bootstrap-sprockets
|
5
|
+
//= require select2
|
6
|
+
//= require_tree .
|
7
|
+
|
8
|
+
$(document).on('turbolinks:load', function() {
|
9
|
+
$('.use-select2').select2({
|
10
|
+
placeholder: $(this).data('placeholder')
|
11
|
+
})
|
12
|
+
})
|
@@ -0,0 +1,13 @@
|
|
1
|
+
.select2-selection, .select2-selection__arrow {
|
2
|
+
height: 34px !important;
|
3
|
+
}
|
4
|
+
.select2-selection__rendered {
|
5
|
+
line-height: 34px !important;
|
6
|
+
}
|
7
|
+
|
8
|
+
.select2-selection {
|
9
|
+
border-color: #ccc !important;
|
10
|
+
}
|
11
|
+
.select2-results__option--highlighted {
|
12
|
+
background-color: $main-color !important;
|
13
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require font-awesome
|
14
|
+
*= require select2
|
15
|
+
*= require select2-bootstrap
|
16
|
+
*/
|
17
|
+
|
18
|
+
$spacing: 16px;
|
19
|
+
|
20
|
+
@import 'bootstrap-sprockets';
|
21
|
+
@import 'bootstrap';
|
22
|
+
|
23
|
+
@import 'colors';
|
24
|
+
@import 'common';
|
25
|
+
@import 'error';
|
@@ -0,0 +1,77 @@
|
|
1
|
+
body {
|
2
|
+
color: $text-color;
|
3
|
+
}
|
4
|
+
|
5
|
+
a {
|
6
|
+
color: $main-color;
|
7
|
+
}
|
8
|
+
a:hover {
|
9
|
+
color: $main-color;
|
10
|
+
text-decoration: none;
|
11
|
+
}
|
12
|
+
|
13
|
+
th {
|
14
|
+
color: $main-color;
|
15
|
+
}
|
16
|
+
|
17
|
+
.panel {
|
18
|
+
border-color: $main-color;
|
19
|
+
}
|
20
|
+
.panel-danger {
|
21
|
+
border-color: #ddd;
|
22
|
+
.panel-heading {
|
23
|
+
color: white;
|
24
|
+
text-shadow: 0 -1px 0 #900;
|
25
|
+
background-color: #df3e3e;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
.pagination {
|
30
|
+
li > a {
|
31
|
+
color: $main-color;
|
32
|
+
border-color: $main-color;
|
33
|
+
}
|
34
|
+
li > a:hover {
|
35
|
+
color: $main-color;
|
36
|
+
background-color: lighten($main-color, 20%);
|
37
|
+
border-color: lighten($main-color, 20%);
|
38
|
+
}
|
39
|
+
li.active > a {
|
40
|
+
background-color: $main-color;
|
41
|
+
border-color: $main-color;
|
42
|
+
}
|
43
|
+
li.active > a:hover {
|
44
|
+
background-color: lighten($main-color, 20%);;
|
45
|
+
border-color: lighten($main-color, 20%);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
.center {
|
50
|
+
text-align: center;
|
51
|
+
}
|
52
|
+
|
53
|
+
.btn-primary {
|
54
|
+
color: #fff;
|
55
|
+
text-shadow: 0 -1px 0 rgba(0,0,0,0.15);
|
56
|
+
background-color: #60b044;
|
57
|
+
background-image: -webkit-linear-gradient(#8add6d, #60b044);
|
58
|
+
background-image: linear-gradient(#8add6d, #60b044);
|
59
|
+
border-color: #5ca941;
|
60
|
+
}
|
61
|
+
.btn-primary:hover {
|
62
|
+
color: #fff;
|
63
|
+
background-color: #569e3d;
|
64
|
+
background-image: -webkit-linear-gradient(#79d858, #569e3d);
|
65
|
+
background-image: linear-gradient(#79d858, #569e3d);
|
66
|
+
border-color: #4a993e;
|
67
|
+
}
|
68
|
+
|
69
|
+
.form-control:hover {
|
70
|
+
border-color: $main-color;
|
71
|
+
}
|
72
|
+
|
73
|
+
:focus {
|
74
|
+
outline-color: $main-color;
|
75
|
+
border-color: $main-color !important;
|
76
|
+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px $main-color !important;
|
77
|
+
}
|
@@ -0,0 +1,82 @@
|
|
1
|
+
//= require font-awesome
|
2
|
+
//= require select2
|
3
|
+
//= require select2-bootstrap
|
4
|
+
|
5
|
+
$spacing: 16px;
|
6
|
+
|
7
|
+
@import 'bootstrap-sprockets';
|
8
|
+
@import 'bootstrap';
|
9
|
+
|
10
|
+
@import 'colors';
|
11
|
+
@import 'common';
|
12
|
+
@import '_select2';
|
13
|
+
|
14
|
+
#top-nav-buttons {
|
15
|
+
position: fixed;
|
16
|
+
top: 0;
|
17
|
+
width: 100%;
|
18
|
+
z-index: 1000;
|
19
|
+
a:first-child {
|
20
|
+
border-top-left-radius: 0;
|
21
|
+
}
|
22
|
+
a:last-child {
|
23
|
+
border-top-right-radius: 0;
|
24
|
+
}
|
25
|
+
a {
|
26
|
+
border-color: $main-color;
|
27
|
+
}
|
28
|
+
a:hover {
|
29
|
+
background-color: lighten($main-color, 20%);
|
30
|
+
border-color: lighten($main-color, 20%);
|
31
|
+
}
|
32
|
+
a.active {
|
33
|
+
background-color: $main-color;
|
34
|
+
color: white;
|
35
|
+
}
|
36
|
+
a.active:hover {
|
37
|
+
background-color: lighten($main-color, 20%);
|
38
|
+
border-color: lighten($main-color, 20%);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
#main-container {
|
43
|
+
width: 100%;
|
44
|
+
#main-content {
|
45
|
+
margin-top: 50px;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
.model-index-panel {
|
50
|
+
width: 100%;
|
51
|
+
table {
|
52
|
+
margin-bottom: 0;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
.model-new-panel, .model-edit-panel {
|
56
|
+
max-width: 600px;
|
57
|
+
margin-left: auto;
|
58
|
+
margin-right: auto;
|
59
|
+
}
|
60
|
+
|
61
|
+
#dashboard-index-buttons {
|
62
|
+
display: inline-block;
|
63
|
+
margin-right: $spacing;
|
64
|
+
}
|
65
|
+
#new_q {
|
66
|
+
display: inline-block;
|
67
|
+
}
|
68
|
+
|
69
|
+
.search-fields {
|
70
|
+
display: inline-flex;
|
71
|
+
.form-group {
|
72
|
+
display: inline-flex;
|
73
|
+
margin-right: 5px;
|
74
|
+
margin-bottom: 0;
|
75
|
+
}
|
76
|
+
.form-group:last-child {
|
77
|
+
margin-right: 0;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
.search-buttons {
|
81
|
+
display: inline-flex;
|
82
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Carload
|
2
|
+
class ApplicationController < ::ApplicationController
|
3
|
+
include Pundit
|
4
|
+
rescue_from Pundit::NotAuthorizedError, with: :rescue_not_authorized_error
|
5
|
+
|
6
|
+
protect_from_forgery with: :exception
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def rescue_not_authorized_error
|
11
|
+
if Carload.auth_solution == :devise
|
12
|
+
if user_signed_in?
|
13
|
+
message = I18n.t("carload.error.message.#{params[:controller].split('/').last}_#{params[:action]}")
|
14
|
+
redirect_to unauthorized_error_path(message: message)
|
15
|
+
else
|
16
|
+
authenticate_user!
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require_dependency 'carload/application_controller'
|
2
|
+
|
3
|
+
module Carload
|
4
|
+
class DashboardController < ApplicationController
|
5
|
+
layout 'carload/dashboard'
|
6
|
+
rescue_from ActionView::MissingTemplate, with: :rescue_missing_template
|
7
|
+
rescue_from Carload::UnmanagedModelError, with: :rescue_unmanaged_model_error
|
8
|
+
|
9
|
+
before_action :set_model
|
10
|
+
before_action :set_object, only: [:edit, :update, :destroy]
|
11
|
+
|
12
|
+
def index
|
13
|
+
authorize :dashboard, :index? unless Carload.auth_solution == :none
|
14
|
+
@search = @model_class.search(params[:q])
|
15
|
+
@objects = @search.result.page(params[:page])
|
16
|
+
@show_attributes = Dashboard.model(@model_name).index_page[:shows][:attributes] + [:created_at, :updated_at]
|
17
|
+
@search_attributes = Dashboard.model(@model_name).index_page[:searches][:attributes]
|
18
|
+
render "dashboard/#{@model_names}/index.html.erb"
|
19
|
+
end
|
20
|
+
|
21
|
+
def new
|
22
|
+
authorize :dashboard, :new? unless Carload.auth_solution == :none
|
23
|
+
@object = @model_class.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def edit
|
27
|
+
authorize :dashboard, :edit? unless Carload.auth_solution == :none
|
28
|
+
end
|
29
|
+
|
30
|
+
def create
|
31
|
+
authorize :dashboard, :create? unless Carload.auth_solution == :none
|
32
|
+
@object = @model_class.create model_params
|
33
|
+
if @object.save
|
34
|
+
redirect_to action: :index, model: @model_names # TODO: To show page.
|
35
|
+
else
|
36
|
+
render :new
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def update
|
41
|
+
authorize :dashboard, :update? unless Carload.auth_solution == :none
|
42
|
+
if @object.update model_params
|
43
|
+
redirect_to action: :index, model: @model_names # TODO: To show page.
|
44
|
+
else
|
45
|
+
render :edit
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def destroy
|
50
|
+
authorize :dashboard, :destroy? unless Carload.auth_solution == :none
|
51
|
+
@object.destroy
|
52
|
+
redirect_to action: :index, model: @model_names
|
53
|
+
end
|
54
|
+
|
55
|
+
def search
|
56
|
+
params[:action] = :index # To make rescue_missing_template use correct index action.
|
57
|
+
index
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def set_model
|
63
|
+
@model_names = ( params[:model] || Dashboard.default_model ).to_s.pluralize
|
64
|
+
@model_name = @model_names.singularize.to_sym
|
65
|
+
raise Carload::UnmanagedModelError.new(@model_name) if not Dashboard.models.keys.include? @model_name
|
66
|
+
@model_class = @model_name.to_s.classify.constantize
|
67
|
+
end
|
68
|
+
|
69
|
+
def set_object
|
70
|
+
@object = @model_class.find params[:id]
|
71
|
+
end
|
72
|
+
|
73
|
+
def model_params
|
74
|
+
params.require(@model_name).permit(Dashboard.model(@model_name).attributes[:permitted])
|
75
|
+
end
|
76
|
+
|
77
|
+
def rescue_missing_template exception
|
78
|
+
render params[:action]
|
79
|
+
end
|
80
|
+
|
81
|
+
def rescue_unmanaged_model_error exception
|
82
|
+
redirect_to dashboard_error_path(message: exception.message)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_dependency 'carload/application_controller'
|
2
|
+
|
3
|
+
module Carload
|
4
|
+
class ErrorsController < ApplicationController
|
5
|
+
layout 'carload/application'
|
6
|
+
|
7
|
+
before_action :set_message
|
8
|
+
|
9
|
+
def dashboard_error
|
10
|
+
end
|
11
|
+
|
12
|
+
def unauthorized_error
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def set_message
|
18
|
+
@message = params[:message]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Carload
|
2
|
+
module DashboardHelper
|
3
|
+
def generate_input form, model_name, attribute_name, column
|
4
|
+
if column.type == :integer and attribute_name =~ /_id/
|
5
|
+
associated_model = attribute_name.sub('_id', '')
|
6
|
+
label_attribute = Dashboard.model(model_name).associated_models[associated_model.to_sym]
|
7
|
+
form.association associated_model,
|
8
|
+
label_method: label_attribute,
|
9
|
+
label: t("activerecord.models.#{associated_model}"),
|
10
|
+
input_html: {
|
11
|
+
class: 'use-select2',
|
12
|
+
data: {
|
13
|
+
placeholder: t('carload.placeholder.select', thing: t("activerecord.attributes.#{associated_model}.#{label_attribute}"))
|
14
|
+
}
|
15
|
+
}
|
16
|
+
else
|
17
|
+
form.input attribute_name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_show object, attribute
|
22
|
+
case attribute
|
23
|
+
when Symbol
|
24
|
+
object.send attribute
|
25
|
+
when String
|
26
|
+
eval "object.#{attribute}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class ApplicationPolicy
|
2
|
+
attr_reader :user, :record
|
3
|
+
|
4
|
+
def initialize(user, record)
|
5
|
+
@user = user
|
6
|
+
@record = record
|
7
|
+
end
|
8
|
+
|
9
|
+
def index?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
def show?
|
14
|
+
scope.where(:id => record.id).exists?
|
15
|
+
end
|
16
|
+
|
17
|
+
def create?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def new?
|
22
|
+
create?
|
23
|
+
end
|
24
|
+
|
25
|
+
def update?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def edit?
|
30
|
+
update?
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy?
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def scope
|
38
|
+
Pundit.policy_scope!(user, record.class)
|
39
|
+
end
|
40
|
+
|
41
|
+
class Scope
|
42
|
+
attr_reader :user, :scope
|
43
|
+
|
44
|
+
def initialize(user, scope)
|
45
|
+
@user = user
|
46
|
+
@scope = scope
|
47
|
+
end
|
48
|
+
|
49
|
+
def resolve
|
50
|
+
scope
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class DashboardPolicy < Struct.new(:user, :dashboard)
|
2
|
+
[:index, :new, :edit, :destroy].each do |action|
|
3
|
+
define_method :"#{action}?" do
|
4
|
+
return true if Carload.auth_solution == :none
|
5
|
+
return false if not user
|
6
|
+
action = :all if not Carload.dashboard[:permits_user][action]
|
7
|
+
Array(Carload.dashboard[:permits_user][action]).each do |permission|
|
8
|
+
return true if eval "user.#{permission}"
|
9
|
+
end
|
10
|
+
false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def create?
|
15
|
+
new?
|
16
|
+
end
|
17
|
+
|
18
|
+
def update?
|
19
|
+
edit?
|
20
|
+
end
|
21
|
+
end
|