administrate 0.12.0 → 0.20.1
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/Rakefile +0 -2
- data/app/assets/javascripts/administrate/application.js +0 -2
- data/app/assets/javascripts/administrate/components/associative.js +5 -0
- data/app/assets/javascripts/administrate/components/select.js +3 -0
- data/app/assets/javascripts/administrate/components/table.js +1 -1
- data/app/assets/stylesheets/administrate/application.scss +0 -1
- data/app/assets/stylesheets/administrate/base/_forms.scss +1 -1
- data/app/assets/stylesheets/administrate/base/_tables.scss +3 -0
- data/app/assets/stylesheets/administrate/components/_attributes.scss +4 -3
- data/app/assets/stylesheets/administrate/components/_buttons.scss +20 -0
- data/app/assets/stylesheets/administrate/components/_cells.scss +2 -0
- data/app/assets/stylesheets/administrate/components/_field-unit.scss +24 -4
- data/app/assets/stylesheets/administrate/components/_flashes.scss +2 -10
- data/app/assets/stylesheets/administrate/components/_main-content.scss +1 -0
- data/app/assets/stylesheets/administrate/components/_navigation.scss +2 -3
- data/app/assets/stylesheets/administrate/library/_variables.scss +11 -9
- data/app/controllers/administrate/application_controller.rb +127 -25
- data/app/controllers/concerns/administrate/punditize.rb +44 -20
- data/app/helpers/administrate/application_helper.rb +56 -20
- data/app/views/administrate/application/_collection.html.erb +26 -29
- data/app/views/administrate/application/_collection_header_actions.html.erb +4 -0
- data/app/views/administrate/application/_collection_item_actions.html.erb +17 -0
- data/app/views/administrate/application/_flashes.html.erb +1 -0
- data/app/views/administrate/application/_form.html.erb +20 -5
- data/app/views/administrate/application/_icons.html.erb +1 -1
- data/app/views/administrate/application/_index_header.html.erb +28 -0
- data/app/views/administrate/application/_navigation.html.erb +6 -4
- data/app/views/administrate/application/_pagination.html.erb +1 -0
- data/app/views/administrate/application/edit.html.erb +2 -2
- data/app/views/administrate/application/index.html.erb +9 -29
- data/app/views/administrate/application/new.html.erb +1 -1
- data/app/views/administrate/application/show.html.erb +28 -12
- data/app/views/fields/belongs_to/_form.html.erb +3 -3
- data/app/views/fields/belongs_to/_index.html.erb +1 -1
- data/app/views/fields/belongs_to/_show.html.erb +1 -1
- data/app/views/fields/date/_form.html.erb +22 -0
- data/app/views/fields/date/_index.html.erb +21 -0
- data/app/views/fields/date/_show.html.erb +21 -0
- data/app/views/fields/date_time/_form.html.erb +1 -3
- data/app/views/fields/has_many/_index.html.erb +1 -1
- data/app/views/fields/has_many/_show.html.erb +2 -1
- data/app/views/fields/has_one/_form.html.erb +15 -5
- data/app/views/fields/has_one/_index.html.erb +3 -2
- data/app/views/fields/has_one/_show.html.erb +22 -15
- data/app/views/fields/number/_form.html.erb +1 -1
- data/app/views/fields/polymorphic/_index.html.erb +2 -1
- data/app/views/fields/polymorphic/_show.html.erb +1 -1
- data/app/views/fields/select/_form.html.erb +9 -8
- data/app/views/fields/string/_show.html.erb +2 -2
- data/app/views/fields/text/_show.html.erb +2 -3
- data/app/views/fields/time/_form.html.erb +2 -2
- data/app/views/fields/time/_index.html.erb +3 -1
- data/app/views/fields/time/_show.html.erb +3 -1
- data/app/views/fields/url/_index.html.erb +2 -2
- data/app/views/fields/url/_show.html.erb +2 -2
- data/app/views/layouts/administrate/application.html.erb +2 -1
- data/config/locales/administrate.ar.yml +2 -0
- data/config/locales/administrate.bs.yml +2 -0
- data/config/locales/administrate.ca.yml +2 -0
- data/config/locales/administrate.da.yml +2 -0
- data/config/locales/administrate.de.yml +4 -2
- data/config/locales/administrate.en.yml +2 -0
- data/config/locales/administrate.es.yml +2 -0
- data/config/locales/administrate.fi.yml +30 -0
- data/config/locales/administrate.fr.yml +4 -2
- data/config/locales/administrate.id.yml +2 -0
- data/config/locales/administrate.it.yml +2 -0
- data/config/locales/administrate.ja.yml +7 -5
- data/config/locales/administrate.ko.yml +2 -0
- data/config/locales/administrate.nl.yml +7 -5
- data/config/locales/administrate.pl.yml +2 -0
- data/config/locales/administrate.pt-BR.yml +4 -2
- data/config/locales/administrate.pt.yml +4 -2
- data/config/locales/administrate.ru.yml +2 -0
- data/config/locales/administrate.sl.yml +30 -0
- data/config/locales/{administrate.al.yml → administrate.sq.yml} +3 -1
- data/config/locales/administrate.sv.yml +2 -0
- data/config/locales/administrate.tr.yml +30 -0
- data/config/locales/administrate.uk.yml +2 -0
- data/config/locales/administrate.vi.yml +2 -0
- data/config/locales/administrate.zh-CN.yml +2 -0
- data/config/locales/administrate.zh-TW.yml +2 -0
- data/docs/adding_controllers_without_related_model.md +52 -0
- data/docs/adding_custom_field_types.md +3 -1
- data/docs/authentication.md +3 -1
- data/docs/authorization.md +47 -22
- data/docs/customizing_attribute_partials.md +4 -1
- data/docs/customizing_controller_actions.md +67 -1
- data/docs/customizing_dashboards.md +171 -40
- data/docs/customizing_page_views.md +18 -4
- data/docs/extending_administrate.md +27 -0
- data/docs/getting_started.md +35 -11
- data/docs/guides/customising_search.md +149 -0
- data/docs/guides/hiding_dashboards_from_sidebar.md +21 -0
- data/docs/guides/scoping_has_many_relations.md +27 -0
- data/docs/guides.md +7 -0
- data/docs/rails_api.md +5 -3
- data/lib/administrate/base_dashboard.rb +73 -14
- data/lib/administrate/custom_dashboard.rb +15 -0
- data/lib/administrate/engine.rb +9 -2
- data/lib/administrate/field/associative.rb +61 -7
- data/lib/administrate/field/base.rb +39 -9
- data/lib/administrate/field/belongs_to.rb +22 -5
- data/lib/administrate/field/date.rb +20 -0
- data/lib/administrate/field/deferred.rb +26 -3
- data/lib/administrate/field/has_many.rb +35 -8
- data/lib/administrate/field/has_one.rb +36 -12
- data/lib/administrate/field/number.rb +13 -2
- data/lib/administrate/field/polymorphic.rb +7 -6
- data/lib/administrate/field/select.rb +23 -4
- data/lib/administrate/field/time.rb +11 -0
- data/lib/administrate/field/url.rb +4 -0
- data/lib/administrate/namespace.rb +5 -1
- data/lib/administrate/not_authorized_error.rb +20 -0
- data/lib/administrate/order.rb +85 -19
- data/lib/administrate/page/base.rb +5 -3
- data/lib/administrate/page/collection.rb +1 -0
- data/lib/administrate/page/form.rb +12 -4
- data/lib/administrate/page/show.rb +10 -2
- data/lib/administrate/resource_resolver.rb +4 -3
- data/lib/administrate/search.rb +47 -36
- data/lib/administrate/version.rb +1 -1
- data/lib/administrate/view_generator.rb +14 -3
- data/lib/administrate.rb +42 -0
- data/lib/generators/administrate/dashboard/dashboard_generator.rb +38 -16
- data/lib/generators/administrate/dashboard/templates/controller.rb.erb +23 -11
- data/lib/generators/administrate/dashboard/templates/dashboard.rb.erb +4 -4
- data/lib/generators/administrate/install/install_generator.rb +43 -2
- data/lib/generators/administrate/install/templates/application_controller.rb.erb +4 -4
- data/lib/generators/administrate/routes/routes_generator.rb +26 -27
- data/lib/generators/administrate/test_record.rb +21 -0
- data/lib/generators/administrate/views/views_generator.rb +5 -4
- metadata +57 -78
- data/app/assets/javascripts/administrate/components/date_time_picker.js +0 -10
- data/app/assets/javascripts/administrate/components/has_many_form.js +0 -3
- data/config/i18n-tasks.yml +0 -18
- data/config/routes.rb +0 -2
- data/config/unicorn.rb +0 -30
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8e5544a7c600e80f4f0059f7b4aea8903e46d926b06dea598660baa758ed67ec
|
|
4
|
+
data.tar.gz: b4aefefcdb03dc10c0570e8d6b1a15629c4a3cee9f5ceb46d306e2b3a57e2454
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 18ac7ba09f2f7e36d5c86d492fda86cf2f31239146bcac7dacd47eb124fc793e9c425f1646cdcdcce8a672b1666322b6178cf5a602bc358d794e315050f94d02
|
|
7
|
+
data.tar.gz: 183d4aafdeeef34031acf4f0fbd29401d39ad368a2b889d509d36560dfcd2b222043ddde8504fddfddcf505017467e6eec74848c422b960233b3492e9198e06d
|
data/Rakefile
CHANGED
|
@@ -13,7 +13,7 @@ $(function() {
|
|
|
13
13
|
var dataUrl = $(event.target).closest("tr").data("url");
|
|
14
14
|
var selection = window.getSelection().toString();
|
|
15
15
|
if (selection.length === 0 && dataUrl) {
|
|
16
|
-
window.location = dataUrl;
|
|
16
|
+
window.location = window.location.protocol + '//' + window.location.host + dataUrl;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
};
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
clear: left;
|
|
4
4
|
float: left;
|
|
5
5
|
margin-bottom: $base-spacing;
|
|
6
|
-
margin-top: 0;
|
|
6
|
+
margin-top: 0.25em;
|
|
7
7
|
text-align: right;
|
|
8
|
-
width: calc(
|
|
8
|
+
width: calc(20% - 1rem);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
.preserve-whitespace {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
float: left;
|
|
18
18
|
margin-bottom: $base-spacing;
|
|
19
19
|
margin-left: 2rem;
|
|
20
|
-
width: calc(
|
|
20
|
+
width: calc(80% - 1rem);
|
|
21
|
+
word-break: break-word;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
.attribute--nested {
|
|
@@ -41,3 +41,23 @@ input[type="submit"],
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
.button--alt {
|
|
46
|
+
background-color: transparent;
|
|
47
|
+
border: $base-border;
|
|
48
|
+
border-color: $blue;
|
|
49
|
+
color: $blue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.button--danger {
|
|
53
|
+
background-color: $red;
|
|
54
|
+
|
|
55
|
+
&:hover {
|
|
56
|
+
background-color: mix($black, $red, 20%);
|
|
57
|
+
color: $white;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.button--nav {
|
|
62
|
+
margin-bottom: $base-spacing;
|
|
63
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
@include administrate-clearfix;
|
|
3
3
|
align-items: center;
|
|
4
4
|
display: flex;
|
|
5
|
+
flex-wrap: wrap;
|
|
5
6
|
margin-bottom: $base-spacing;
|
|
6
7
|
position: relative;
|
|
7
8
|
width: 100%;
|
|
@@ -17,20 +18,39 @@
|
|
|
17
18
|
.field-unit__field {
|
|
18
19
|
float: left;
|
|
19
20
|
margin-left: 2rem;
|
|
20
|
-
width:
|
|
21
|
+
max-width: 50rem;
|
|
22
|
+
width: 100%;
|
|
23
|
+
|
|
24
|
+
.optgroup-header {
|
|
25
|
+
font-weight: $bold-font-weight;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.field-unit__hint {
|
|
30
|
+
font-size: 90%;
|
|
31
|
+
margin-left: calc(15% + 2rem);
|
|
32
|
+
width: 100%;
|
|
21
33
|
}
|
|
22
34
|
|
|
23
35
|
.field-unit--nested {
|
|
24
36
|
border: $base-border;
|
|
25
37
|
margin-left: 7.5%;
|
|
38
|
+
max-width: 60rem;
|
|
26
39
|
padding: $small-spacing;
|
|
27
|
-
width:
|
|
40
|
+
width: 100%;
|
|
28
41
|
|
|
29
42
|
.field-unit__field {
|
|
30
|
-
width:
|
|
43
|
+
width: 100%;
|
|
31
44
|
}
|
|
32
45
|
|
|
33
46
|
.field-unit__label {
|
|
34
|
-
width:
|
|
47
|
+
width: 10rem;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.field-unit--required {
|
|
52
|
+
label::after {
|
|
53
|
+
color: $red;
|
|
54
|
+
content: " *";
|
|
35
55
|
}
|
|
36
56
|
}
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
$base-spacing: 1.5em !default;
|
|
2
|
-
$flashes: (
|
|
3
|
-
"alert": #fff6bf,
|
|
4
|
-
"error": #fbe3e4,
|
|
5
|
-
"notice": #e5edf8,
|
|
6
|
-
"success": #e6efc2,
|
|
7
|
-
) !default;
|
|
8
|
-
|
|
9
1
|
@each $flash-type, $color in $flashes {
|
|
10
2
|
.flash-#{$flash-type} {
|
|
11
3
|
background-color: $color;
|
|
12
4
|
color: mix($black, $color, 60%);
|
|
13
5
|
display: block;
|
|
14
|
-
margin-bottom: $base-spacing
|
|
15
|
-
padding: $base-spacing
|
|
6
|
+
margin-bottom: $base-spacing * 0.5;
|
|
7
|
+
padding: $base-spacing * 0.5;
|
|
16
8
|
text-align: center;
|
|
17
9
|
|
|
18
10
|
a {
|
|
@@ -2,9 +2,8 @@ $_navigation-link-padding: 0.6em;
|
|
|
2
2
|
|
|
3
3
|
.navigation {
|
|
4
4
|
flex: 1 0 10rem;
|
|
5
|
-
padding
|
|
6
|
-
padding-
|
|
7
|
-
padding-top: $base-spacing;
|
|
5
|
+
padding: $base-spacing;
|
|
6
|
+
padding-left: 0;
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
.navigation__link {
|
|
@@ -14,7 +14,7 @@ $heading-line-height: 1.2 !default;
|
|
|
14
14
|
// Other Sizes
|
|
15
15
|
$base-border-radius: 4px !default;
|
|
16
16
|
$base-spacing: $base-line-height * 1em !default;
|
|
17
|
-
$small-spacing: $base-spacing
|
|
17
|
+
$small-spacing: $base-spacing * 0.5 !default;
|
|
18
18
|
|
|
19
19
|
// Colors
|
|
20
20
|
$white: #fff !default;
|
|
@@ -22,8 +22,10 @@ $black: #000 !default;
|
|
|
22
22
|
|
|
23
23
|
$blue: #1976d2 !default;
|
|
24
24
|
$red: #d32f2f !default;
|
|
25
|
-
$light-yellow: #
|
|
26
|
-
$light-
|
|
25
|
+
$light-yellow: #fff6bf !default;
|
|
26
|
+
$light-red: #fbe3e4 !default;
|
|
27
|
+
$light-green: #e6efc2 !default;
|
|
28
|
+
$light-blue: #e5edf8 !default;
|
|
27
29
|
|
|
28
30
|
$grey-0: #f6f7f7 !default;
|
|
29
31
|
$grey-1: #dfe0e1 !default;
|
|
@@ -47,12 +49,12 @@ $focus-outline: $focus-outline-width solid $focus-outline-color;
|
|
|
47
49
|
$focus-outline-offset: 1px;
|
|
48
50
|
|
|
49
51
|
// Flash Colors
|
|
50
|
-
$
|
|
51
|
-
alert: $light-yellow,
|
|
52
|
-
error: $red,
|
|
53
|
-
notice:
|
|
54
|
-
success: $light-green
|
|
55
|
-
);
|
|
52
|
+
$flashes: (
|
|
53
|
+
"alert": $light-yellow,
|
|
54
|
+
"error": $light-red,
|
|
55
|
+
"notice": $light-blue,
|
|
56
|
+
"success": $light-green
|
|
57
|
+
) !default;
|
|
56
58
|
|
|
57
59
|
// Border
|
|
58
60
|
$base-border-color: $grey-1 !default;
|
|
@@ -3,13 +3,12 @@ module Administrate
|
|
|
3
3
|
protect_from_forgery with: :exception
|
|
4
4
|
|
|
5
5
|
def index
|
|
6
|
+
authorize_resource(resource_class)
|
|
6
7
|
search_term = params[:search].to_s.strip
|
|
7
|
-
resources =
|
|
8
|
-
dashboard_class,
|
|
9
|
-
search_term).run
|
|
8
|
+
resources = filter_resources(scoped_resource, search_term: search_term)
|
|
10
9
|
resources = apply_collection_includes(resources)
|
|
11
10
|
resources = order.apply(resources)
|
|
12
|
-
resources = resources
|
|
11
|
+
resources = paginate_resources(resources)
|
|
13
12
|
page = Administrate::Page::Collection.new(dashboard, order: order)
|
|
14
13
|
|
|
15
14
|
render locals: {
|
|
@@ -27,7 +26,7 @@ module Administrate
|
|
|
27
26
|
end
|
|
28
27
|
|
|
29
28
|
def new
|
|
30
|
-
resource =
|
|
29
|
+
resource = new_resource
|
|
31
30
|
authorize_resource(resource)
|
|
32
31
|
render locals: {
|
|
33
32
|
page: Administrate::Page::Form.new(dashboard, resource),
|
|
@@ -41,31 +40,32 @@ module Administrate
|
|
|
41
40
|
end
|
|
42
41
|
|
|
43
42
|
def create
|
|
44
|
-
resource =
|
|
43
|
+
resource = new_resource(resource_params)
|
|
45
44
|
authorize_resource(resource)
|
|
46
45
|
|
|
47
46
|
if resource.save
|
|
47
|
+
yield(resource) if block_given?
|
|
48
48
|
redirect_to(
|
|
49
|
-
|
|
49
|
+
after_resource_created_path(resource),
|
|
50
50
|
notice: translate_with_resource("create.success"),
|
|
51
51
|
)
|
|
52
52
|
else
|
|
53
53
|
render :new, locals: {
|
|
54
54
|
page: Administrate::Page::Form.new(dashboard, resource),
|
|
55
|
-
}
|
|
55
|
+
}, status: :unprocessable_entity
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def update
|
|
60
60
|
if requested_resource.update(resource_params)
|
|
61
61
|
redirect_to(
|
|
62
|
-
|
|
62
|
+
after_resource_updated_path(requested_resource),
|
|
63
63
|
notice: translate_with_resource("update.success"),
|
|
64
64
|
)
|
|
65
65
|
else
|
|
66
66
|
render :edit, locals: {
|
|
67
67
|
page: Administrate::Page::Form.new(dashboard, requested_resource),
|
|
68
|
-
}
|
|
68
|
+
}, status: :unprocessable_entity
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
|
@@ -75,25 +75,61 @@ module Administrate
|
|
|
75
75
|
else
|
|
76
76
|
flash[:error] = requested_resource.errors.full_messages.join("<br/>")
|
|
77
77
|
end
|
|
78
|
-
redirect_to
|
|
78
|
+
redirect_to after_resource_destroyed_path(requested_resource)
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
private
|
|
82
82
|
|
|
83
|
+
def filter_resources(resources, search_term:)
|
|
84
|
+
Administrate::Search.new(
|
|
85
|
+
resources,
|
|
86
|
+
dashboard,
|
|
87
|
+
search_term,
|
|
88
|
+
).run
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def after_resource_destroyed_path(_requested_resource)
|
|
92
|
+
{ action: :index }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def after_resource_created_path(requested_resource)
|
|
96
|
+
[namespace, requested_resource]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def after_resource_updated_path(requested_resource)
|
|
100
|
+
[namespace, requested_resource]
|
|
101
|
+
end
|
|
102
|
+
|
|
83
103
|
helper_method :nav_link_state
|
|
84
104
|
def nav_link_state(resource)
|
|
85
|
-
|
|
105
|
+
underscore_resource = resource.to_s.split("/").join("__")
|
|
106
|
+
resource_name.to_s.pluralize == underscore_resource ? :active : :inactive
|
|
86
107
|
end
|
|
87
108
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
109
|
+
# Whether the named action route exists for the resource class.
|
|
110
|
+
#
|
|
111
|
+
# @param resource [Class, String, Symbol] A class of resources, or the name
|
|
112
|
+
# of a class of resources.
|
|
113
|
+
# @param action_name [String, Symbol] The name of an action that might be
|
|
114
|
+
# possible to perform on a resource or resource class.
|
|
115
|
+
# @return [Boolean] `true` if a route exists for the resource class and the
|
|
116
|
+
# action. `false` otherwise.
|
|
117
|
+
def existing_action?(resource, action_name)
|
|
118
|
+
routes.include?([resource.to_s.underscore.pluralize, action_name.to_s])
|
|
93
119
|
end
|
|
120
|
+
helper_method :existing_action?
|
|
121
|
+
|
|
122
|
+
# @deprecated Use {#existing_action} instead. Note that, in
|
|
123
|
+
# {#existing_action}, the order of parameters is reversed and
|
|
124
|
+
# there is no default value for the `resource` parameter.
|
|
125
|
+
def valid_action?(action_name, resource = resource_class)
|
|
126
|
+
Administrate.warn_of_deprecated_authorization_method(__method__)
|
|
127
|
+
existing_action?(resource, action_name)
|
|
128
|
+
end
|
|
129
|
+
helper_method :valid_action?
|
|
94
130
|
|
|
95
131
|
def routes
|
|
96
|
-
@routes ||= Namespace.new(namespace).routes
|
|
132
|
+
@routes ||= Namespace.new(namespace).routes.to_set
|
|
97
133
|
end
|
|
98
134
|
|
|
99
135
|
def records_per_page
|
|
@@ -102,11 +138,44 @@ module Administrate
|
|
|
102
138
|
|
|
103
139
|
def order
|
|
104
140
|
@order ||= Administrate::Order.new(
|
|
105
|
-
|
|
106
|
-
|
|
141
|
+
sorting_attribute,
|
|
142
|
+
sorting_direction,
|
|
143
|
+
association_attribute: order_by_field(
|
|
144
|
+
dashboard_attribute(sorting_attribute),
|
|
145
|
+
),
|
|
107
146
|
)
|
|
108
147
|
end
|
|
109
148
|
|
|
149
|
+
def order_by_field(dashboard)
|
|
150
|
+
return unless dashboard.try(:options)
|
|
151
|
+
|
|
152
|
+
dashboard.options.fetch(:order, nil)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def dashboard_attribute(attribute)
|
|
156
|
+
dashboard.attribute_types[attribute.to_sym] if attribute
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def sorting_attribute
|
|
160
|
+
sorting_params.fetch(:order) { default_sorting_attribute }
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def default_sorting_attribute
|
|
164
|
+
nil
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def sorting_direction
|
|
168
|
+
sorting_params.fetch(:direction) { default_sorting_direction }
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def default_sorting_direction
|
|
172
|
+
nil
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def sorting_params
|
|
176
|
+
Hash.try_convert(request.query_parameters[resource_name]) || {}
|
|
177
|
+
end
|
|
178
|
+
|
|
110
179
|
def dashboard
|
|
111
180
|
@dashboard ||= dashboard_class.new
|
|
112
181
|
end
|
|
@@ -133,7 +202,7 @@ module Administrate
|
|
|
133
202
|
|
|
134
203
|
def resource_params
|
|
135
204
|
params.require(resource_class.model_name.param_key).
|
|
136
|
-
permit(dashboard.permitted_attributes).
|
|
205
|
+
permit(dashboard.permitted_attributes(action_name)).
|
|
137
206
|
transform_values { |v| read_param_value(v) }
|
|
138
207
|
end
|
|
139
208
|
|
|
@@ -144,6 +213,10 @@ module Administrate
|
|
|
144
213
|
else
|
|
145
214
|
raise "Unrecognised param data: #{data.inspect}"
|
|
146
215
|
end
|
|
216
|
+
elsif data.is_a?(ActionController::Parameters)
|
|
217
|
+
data.transform_values { |v| read_param_value(v) }
|
|
218
|
+
elsif data.is_a?(String) && data.blank?
|
|
219
|
+
nil
|
|
147
220
|
else
|
|
148
221
|
data
|
|
149
222
|
end
|
|
@@ -153,6 +226,7 @@ module Administrate
|
|
|
153
226
|
to: :resource_resolver
|
|
154
227
|
helper_method :namespace
|
|
155
228
|
helper_method :resource_name
|
|
229
|
+
helper_method :resource_class
|
|
156
230
|
|
|
157
231
|
def resource_resolver
|
|
158
232
|
@resource_resolver ||=
|
|
@@ -172,18 +246,46 @@ module Administrate
|
|
|
172
246
|
).any? { |_name, attribute| attribute.searchable? }
|
|
173
247
|
end
|
|
174
248
|
|
|
175
|
-
|
|
249
|
+
# Whether the current user is authorized to perform the named action on the
|
|
250
|
+
# resource.
|
|
251
|
+
#
|
|
252
|
+
# @param _resource [ActiveRecord::Base, Class, String, Symbol] The
|
|
253
|
+
# temptative target of the action, or the name of its class.
|
|
254
|
+
# @param _action_name [String, Symbol] The name of an action that might be
|
|
255
|
+
# possible to perform on a resource or resource class.
|
|
256
|
+
# @return [Boolean] `true` if the current user is authorized to perform the
|
|
257
|
+
# action on the resource. `false` otherwise.
|
|
258
|
+
def authorized_action?(_resource, _action_name)
|
|
176
259
|
true
|
|
177
260
|
end
|
|
261
|
+
helper_method :authorized_action?
|
|
262
|
+
|
|
263
|
+
# @deprecated Use {#authorized_action} instead. Note that the order of
|
|
264
|
+
# parameters is reversed in {#authorized_action}.
|
|
265
|
+
def show_action?(action, resource)
|
|
266
|
+
Administrate.warn_of_deprecated_authorization_method(__method__)
|
|
267
|
+
authorized_action?(resource, action)
|
|
268
|
+
end
|
|
178
269
|
helper_method :show_action?
|
|
179
270
|
|
|
180
|
-
def new_resource
|
|
181
|
-
resource_class.new
|
|
271
|
+
def new_resource(params = {})
|
|
272
|
+
resource_class.new(params)
|
|
182
273
|
end
|
|
183
274
|
helper_method :new_resource
|
|
184
275
|
|
|
185
276
|
def authorize_resource(resource)
|
|
186
|
-
resource
|
|
277
|
+
if authorized_action?(resource, action_name)
|
|
278
|
+
resource
|
|
279
|
+
else
|
|
280
|
+
raise Administrate::NotAuthorizedError.new(
|
|
281
|
+
action: action_name,
|
|
282
|
+
resource: resource,
|
|
283
|
+
)
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def paginate_resources(resources)
|
|
288
|
+
resources.page(params[:_page]).per(records_per_page)
|
|
187
289
|
end
|
|
188
290
|
end
|
|
189
291
|
end
|
|
@@ -2,35 +2,59 @@ module Administrate
|
|
|
2
2
|
module Punditize
|
|
3
3
|
if Object.const_defined?("Pundit")
|
|
4
4
|
extend ActiveSupport::Concern
|
|
5
|
-
include Pundit
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
if Pundit.const_defined?(:Authorization)
|
|
7
|
+
include Pundit::Authorization
|
|
8
|
+
else
|
|
9
|
+
include Pundit
|
|
10
|
+
end
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
authorize resource
|
|
14
|
-
end
|
|
12
|
+
private
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
end
|
|
14
|
+
def policy_namespace
|
|
15
|
+
[]
|
|
19
16
|
end
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
def scoped_resource
|
|
19
|
+
namespaced_scope = policy_namespace + [super]
|
|
20
|
+
policy_scope!(pundit_user, namespaced_scope)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def authorize_resource(resource)
|
|
24
|
+
namespaced_resource = policy_namespace + [resource]
|
|
25
|
+
authorize namespaced_resource
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def authorized_action?(resource, action)
|
|
29
|
+
namespaced_resource = policy_namespace + [resource]
|
|
30
|
+
policy = Pundit.policy!(pundit_user, namespaced_resource)
|
|
31
|
+
policy.send("#{action}?".to_sym)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def policy_scope!(user, scope)
|
|
35
|
+
policy_scope_class = Pundit::PolicyFinder.new(scope).scope!
|
|
22
36
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
begin
|
|
38
|
+
policy_scope = policy_scope_class.new(user, pundit_model(scope))
|
|
39
|
+
rescue ArgumentError
|
|
40
|
+
raise(Pundit::InvalidConstructorError,
|
|
41
|
+
"Invalid #<#{policy_scope_class}> constructor is called")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if policy_scope.respond_to? :resolve_admin
|
|
45
|
+
Administrate.deprecator.warn(
|
|
46
|
+
"Pundit policy scope `resolve_admin` method is deprecated. " +
|
|
47
|
+
"Please use a namespaced pundit policy instead.",
|
|
48
|
+
)
|
|
49
|
+
policy_scope.resolve_admin
|
|
30
50
|
else
|
|
31
|
-
|
|
51
|
+
policy_scope.resolve
|
|
32
52
|
end
|
|
33
53
|
end
|
|
54
|
+
|
|
55
|
+
def pundit_model(record)
|
|
56
|
+
record.is_a?(Array) ? record.last : record
|
|
57
|
+
end
|
|
34
58
|
end
|
|
35
59
|
end
|
|
36
60
|
end
|