rails_admin_specified_actions 0.2.1.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/README.md +148 -0
- data/Rakefile +2 -0
- data/app/assets/javascripts/rails_admin/rails_admin_specified_actions.coffee +27 -0
- data/app/assets/stylesheets/rails_admin/rails_admin_specified_actions.sass +26 -0
- data/app/views/rails_admin/main/_specified_actions_list.html.slim +30 -0
- data/app/views/rails_admin/main/specified_actions.html.slim +24 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config/locales/specific_actions.en.yml +36 -0
- data/config/locales/specific_actions.ru.yml +35 -0
- data/lib/rails_admin_specified_actions.rb +19 -0
- data/lib/rails_admin_specified_actions/action.rb +203 -0
- data/lib/rails_admin_specified_actions/engine.rb +9 -0
- data/lib/rails_admin_specified_actions/has_actions.rb +150 -0
- data/lib/rails_admin_specified_actions/rails_admin_patch.rb +10 -0
- data/lib/rails_admin_specified_actions/section.rb +19 -0
- data/lib/rails_admin_specified_actions/specified_action.rb +151 -0
- data/lib/rails_admin_specified_actions/version.rb +3 -0
- data/rails_admin_specified_actions.gemspec +32 -0
- data/release.sh +6 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 68fe0c0a44c1a044abea6ccb2119edb208a07baccee6c465c18fc6df2167c794
|
4
|
+
data.tar.gz: 3185483670aac1ae45230a9660935a4d7dee2cffa437ae08967357a6c9c9a112
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3187398a676a7c1cdf0a6235fc34eeb7d156c7acb2e8938a33384b4d0a0dac4793d19e40956c9c9a477dedb19ab5ed35df4d90d3cc26177dfcdc78e908bd731f
|
7
|
+
data.tar.gz: 0e3c52fbf1f58f3e3882966a12134380bec2f2df2f35c741ad5b9a1224ff2e8c23e7abaf7e6ca3daedeb97b749a8792490d2ec3aaa034f83e2ab7546e39b3e47
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
# RailsAdminSpecifiedActions
|
2
|
+
|
3
|
+
Custom actoions for RailsAdmin
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'rails_admin_specified_actions'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install rails_admin_specified_actions
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Add the sort_embedded action for each model or only for models you need
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
RailsAdmin.config do |config|
|
27
|
+
config.actions do
|
28
|
+
...
|
29
|
+
specified_actions do
|
30
|
+
# You can add actions like this
|
31
|
+
|
32
|
+
require_relative 'rails_admin_specified_actions'
|
33
|
+
RailsAdminSpecifiedActions.root_actions(self)
|
34
|
+
|
35
|
+
# also you can add actions like this:
|
36
|
+
config.action :count do
|
37
|
+
object do
|
38
|
+
User
|
39
|
+
end
|
40
|
+
end # will perform `action_name` for `object`: 'User.count'
|
41
|
+
end # for root actions
|
42
|
+
specified_actions_for_collection # for collections actions
|
43
|
+
specified_actions_for_member # for member actions
|
44
|
+
...
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
For root actions you can create config/initializers/rails_admin_specified_actions_root.rb:
|
50
|
+
```ruby
|
51
|
+
module RailsAdminSpecifiedActions
|
52
|
+
|
53
|
+
class << self
|
54
|
+
|
55
|
+
def root_actions(config)
|
56
|
+
config.action :some_root_action do
|
57
|
+
process_block do
|
58
|
+
proc { |obj, args|
|
59
|
+
# `obj` will be nil
|
60
|
+
Rails.cache.clear # or some other global action
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
config.action :some_root_action_with_obj do
|
65
|
+
process_block do
|
66
|
+
proc { |obj, args|
|
67
|
+
# `obj` will be User
|
68
|
+
obj.delete_all # delete them all
|
69
|
+
}
|
70
|
+
end
|
71
|
+
object do
|
72
|
+
Page
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
```
|
82
|
+
or something like this.
|
83
|
+
|
84
|
+
|
85
|
+
For collection and member actions actions:
|
86
|
+
In rails_admin block:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
rails_admin do
|
90
|
+
...
|
91
|
+
specified_actions_for_collection do
|
92
|
+
action :count, :collection do
|
93
|
+
process_block do
|
94
|
+
proc { |model, args|
|
95
|
+
model.all.count
|
96
|
+
}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
...
|
101
|
+
end
|
102
|
+
```
|
103
|
+
or
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
rails_admin do
|
107
|
+
...
|
108
|
+
specified_actions_for_member do
|
109
|
+
action :touch
|
110
|
+
end
|
111
|
+
...
|
112
|
+
end
|
113
|
+
```
|
114
|
+
or both.
|
115
|
+
|
116
|
+
Options for action:
|
117
|
+
|
118
|
+
| Option name | Description | Default value |
|
119
|
+
|--------------------------|------------------------------------------------------------------|---------------|
|
120
|
+
| label | Displayed label | as name |
|
121
|
+
| process_block | Proc for action or action name for \__send__() | nil |
|
122
|
+
| target | :root, :collection or :member | nil |
|
123
|
+
| ajax | If you don`t need reload page | false |
|
124
|
+
| threaded | Create new thread for this action if that can take a long time | false |
|
125
|
+
| can_view_error_backtrace | If you want show error code backtrace. Perhaps, only for admins. | 'only admin' |
|
126
|
+
| can_view_error_message | If you want show detailed errors message | false |
|
127
|
+
| args | Hash of possible arguments (and their types) for action | {} |
|
128
|
+
|
129
|
+
Possible argument types (and field types):
|
130
|
+
|
131
|
+
|
132
|
+
| Type | Field |
|
133
|
+
|--------------------------|------------------------------------------------------------------|
|
134
|
+
| nil | String (`text_field` method) |
|
135
|
+
| :string | String (`text_field` method) |
|
136
|
+
| :boolean | Boolean/Checkbox field (`check_box` method) |
|
137
|
+
| :toggle | Boolean/Checkbox field (`check_box` method) |
|
138
|
+
|
139
|
+
|
140
|
+
## Development
|
141
|
+
|
142
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
143
|
+
|
144
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
145
|
+
|
146
|
+
## Contributing
|
147
|
+
|
148
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/red-rocks/rails_admin_specified_actions.
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
$(document).on "ajax:complete", "#rails_admin_specified_actions_wrapper #rails_admin_specified_actions .form_block form", (e, xhr, opts)->
|
2
|
+
form = $(e.currentTarget)
|
3
|
+
result_block = form.closest(".form_block").siblings(".ajax_result_block")
|
4
|
+
error_block = result_block.siblings(".ajax_error_block")
|
5
|
+
json = $.parseJSON(xhr.responseText)
|
6
|
+
result_block.stop().hide().html(json['result'])
|
7
|
+
error_block.stop().hide().find("*").html("")
|
8
|
+
if json['error']
|
9
|
+
error_block.find(".message").html(json['error']['message']) if json['error']['message']
|
10
|
+
error_block.find(".backtrace").html(json['error']['backtrace']) if json['error']['backtrace']
|
11
|
+
error_block.show(100)
|
12
|
+
result_block.show(100)
|
13
|
+
|
14
|
+
|
15
|
+
$(document).on "ajax:before", "#rails_admin_specified_actions_wrapper #rails_admin_specified_actions .form_block form", (e)->
|
16
|
+
form = $(e.currentTarget)
|
17
|
+
result_block = form.closest(".form_block").siblings(".ajax_result_block")
|
18
|
+
error_block = result_block.siblings(".ajax_error_block")
|
19
|
+
result_block.hide(200)
|
20
|
+
error_block.hide(200)
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
$(document).on "click", ".content > .alert > .show_hide, #rails_admin_specified_actions_wrapper #rails_admin_specified_actions .ajax_error_block .backtrace > .show_hide", (e)->
|
25
|
+
e.preventDefault()
|
26
|
+
$(e.currentTarget).parent().toggleClass('short')
|
27
|
+
return false
|
@@ -0,0 +1,26 @@
|
|
1
|
+
html, body.rails_admin
|
2
|
+
overflow-y: scroll
|
3
|
+
|
4
|
+
.content > .alert, .ajax_error_block .backtrace
|
5
|
+
max-height: auto
|
6
|
+
overflow: hidden
|
7
|
+
&.short
|
8
|
+
max-height: 53px
|
9
|
+
pre
|
10
|
+
margin: 0
|
11
|
+
padding: 0
|
12
|
+
> .show_hide
|
13
|
+
right: -17px
|
14
|
+
|
15
|
+
|
16
|
+
#rails_admin_specified_actions_wrapper
|
17
|
+
#rails_admin_specified_actions
|
18
|
+
|
19
|
+
.ajax_error_block .backtrace
|
20
|
+
background-color: #fcf8e3
|
21
|
+
border-color: #faebcc
|
22
|
+
color: #8a6d3b
|
23
|
+
padding: 0px
|
24
|
+
margin-bottom: 20px
|
25
|
+
border: 1px solid transparent
|
26
|
+
border-radius: 4px
|
@@ -0,0 +1,30 @@
|
|
1
|
+
ul
|
2
|
+
- @actions_list.each do |a|
|
3
|
+
li
|
4
|
+
span= a.label.blank? ? a.name : a.label
|
5
|
+
br
|
6
|
+
- unless a.desc.blank?
|
7
|
+
div= a.desc
|
8
|
+
.form_block
|
9
|
+
ruby:
|
10
|
+
opts = {url: _url, method: :post, data: {}}
|
11
|
+
opts[:data][:remote] = true if a.ajax
|
12
|
+
= form_for "specified_action", opts do |f|
|
13
|
+
= f.hidden_field :name, value: a.name
|
14
|
+
- if a.args and !a.args.blank?
|
15
|
+
- a.args.each_pair do |a_name, a_type|
|
16
|
+
= f.label "args[#{a_name}]", a_name
|
17
|
+
- case a_type and a_type.to_sym
|
18
|
+
- when :string
|
19
|
+
= f.text_field "args[#{a_name}]"
|
20
|
+
- when :boolean, :toggle
|
21
|
+
= f.check_box "args[#{a_name}]"
|
22
|
+
- else
|
23
|
+
= f.text_field "args[#{a_name}]"
|
24
|
+
|
25
|
+
/ = f.submit "сделать"
|
26
|
+
= f.submit a.button_text
|
27
|
+
.ajax_result_block
|
28
|
+
.ajax_error_block
|
29
|
+
.message
|
30
|
+
.backtrace
|
@@ -0,0 +1,24 @@
|
|
1
|
+
= stylesheet_link_tag 'rails_admin/rails_admin_specified_actions'
|
2
|
+
= javascript_include_tag 'rails_admin/rails_admin_specified_actions'
|
3
|
+
|
4
|
+
#rails_admin_specified_actions_wrapper
|
5
|
+
#rails_admin_specified_actions
|
6
|
+
.controls
|
7
|
+
- if @object
|
8
|
+
- if @actions_list.count > 0
|
9
|
+
= render partial: "rails_admin/main/specified_actions_list", locals: {_actions: @actions_list, _url: specified_actions_for_member_path(model_name: @abstract_model, id: @object.id)}
|
10
|
+
- else
|
11
|
+
h3 нечего делать c этой штукой
|
12
|
+
|
13
|
+
- else
|
14
|
+
- if @abstract_model
|
15
|
+
- if @actions_list.count > 0
|
16
|
+
= render partial: "rails_admin/main/specified_actions_list", locals: {_actions: @actions_list, _url: specified_actions_for_collection_path(model_name: @abstract_model)}
|
17
|
+
- else
|
18
|
+
h3 нечего делать c этими штуками
|
19
|
+
|
20
|
+
- else
|
21
|
+
- if @actions_list.count > 0
|
22
|
+
= render partial: "rails_admin/main/specified_actions_list", locals: {_actions: @actions_list, _url: specified_actions_path}
|
23
|
+
- else
|
24
|
+
h3 нечего делать вообще
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "rails_admin_specified_actions"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
en:
|
3
|
+
admin:
|
4
|
+
actions:
|
5
|
+
specified_actions:
|
6
|
+
title: "SpecifiedActions"
|
7
|
+
menu: "SpecifiedActions for %{model_label} '%{object_label}'"
|
8
|
+
breadcrumb: "SpecifiedActions"
|
9
|
+
link: "SpecifiedActions"
|
10
|
+
bulk_link: "SpecifiedActions selected %{model_label_plural}"
|
11
|
+
done: "SpecifiedActions done"
|
12
|
+
confirm: "Are you sure?"
|
13
|
+
|
14
|
+
unknown_error: "Unknown error"
|
15
|
+
|
16
|
+
specified_actions_for_collection:
|
17
|
+
title: "SpecifiedActions"
|
18
|
+
menu: "SpecifiedActions for %{model_label} '%{object_label}'"
|
19
|
+
breadcrumb: "SpecifiedActions"
|
20
|
+
link: "SpecifiedActions"
|
21
|
+
bulk_link: "SpecifiedActions selected %{model_label_plural}"
|
22
|
+
done: "SpecifiedActions done"
|
23
|
+
confirm: "Are you sure?"
|
24
|
+
|
25
|
+
unknown_error: "Unknown error"
|
26
|
+
|
27
|
+
specified_actions_for_member:
|
28
|
+
title: "SpecifiedActions"
|
29
|
+
menu: "SpecifiedActions for %{model_label} '%{object_label}'"
|
30
|
+
breadcrumb: "SpecifiedActions"
|
31
|
+
link: "SpecifiedActions"
|
32
|
+
bulk_link: "SpecifiedActions selected %{model_label_plural}"
|
33
|
+
done: "SpecifiedActions done"
|
34
|
+
confirm: "Are you sure?"
|
35
|
+
|
36
|
+
unknown_error: "Unknown error"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
ru:
|
2
|
+
admin:
|
3
|
+
actions:
|
4
|
+
specified_actions:
|
5
|
+
title: "Действия"
|
6
|
+
menu: "Действия"
|
7
|
+
breadcrumb: "Действия"
|
8
|
+
link: "Действия"
|
9
|
+
bulk_link: "Действия"
|
10
|
+
done: "Действия выполнены"
|
11
|
+
confirm: "Вы уверены?"
|
12
|
+
|
13
|
+
unknown_error: "Неизвестная ошибка"
|
14
|
+
|
15
|
+
specified_actions_for_collection:
|
16
|
+
title: "Действия"
|
17
|
+
menu: "Действия"
|
18
|
+
breadcrumb: "Действия"
|
19
|
+
link: "Действия"
|
20
|
+
bulk_link: "Действия"
|
21
|
+
done: "Действия выполнены"
|
22
|
+
confirm: "Вы уверены?"
|
23
|
+
|
24
|
+
unknown_error: "Неизвестная ошибка"
|
25
|
+
|
26
|
+
specified_actions_for_member:
|
27
|
+
title: "Действия"
|
28
|
+
menu: "Действия"
|
29
|
+
breadcrumb: "Действия"
|
30
|
+
link: "Действия"
|
31
|
+
bulk_link: "Действия"
|
32
|
+
done: "Действия выполнены"
|
33
|
+
confirm: "Вы уверены?"
|
34
|
+
|
35
|
+
unknown_error: "Неизвестная ошибка"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rails_admin_specified_actions/version"
|
2
|
+
require "rails_admin_specified_actions/engine"
|
3
|
+
|
4
|
+
module RailsAdminSpecifiedActions
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def root_actions(config)
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
require "rails_admin"
|
15
|
+
require "rails_admin_specified_actions/rails_admin_patch"
|
16
|
+
|
17
|
+
require "rails_admin_specified_actions/specified_action"
|
18
|
+
require "rails_admin_specified_actions/section"
|
19
|
+
require "rails_admin_specified_actions/action"
|
@@ -0,0 +1,203 @@
|
|
1
|
+
require 'rails_admin/config/actions'
|
2
|
+
require 'rails_admin/config/actions/base'
|
3
|
+
|
4
|
+
require 'rails_admin_specified_actions/specified_action'
|
5
|
+
|
6
|
+
module RailsAdmin
|
7
|
+
module Config
|
8
|
+
module Actions
|
9
|
+
class SpecifiedActions < RailsAdmin::Config::Actions::Base
|
10
|
+
RailsAdmin::Config::Actions.register(self)
|
11
|
+
|
12
|
+
include RailsAdmin::Config::HasActions
|
13
|
+
|
14
|
+
register_instance_option :root? do
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
register_instance_option :collection? do
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
register_instance_option :member do
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
register_instance_option :pjax? do
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
register_instance_option :route_fragment do
|
31
|
+
'specified_actions'
|
32
|
+
end
|
33
|
+
|
34
|
+
register_instance_option :template_name do
|
35
|
+
'specified_actions'
|
36
|
+
end
|
37
|
+
|
38
|
+
register_instance_option :controller do
|
39
|
+
proc do
|
40
|
+
def fallback_location
|
41
|
+
if @object
|
42
|
+
specified_actions_for_member_path(model_name: @abstract_model, id: @object.id)
|
43
|
+
elsif @abstract_model
|
44
|
+
specified_actions_for_collection_path(model_name: @abstract_model)
|
45
|
+
else
|
46
|
+
specified_actions_path
|
47
|
+
end
|
48
|
+
end
|
49
|
+
if @object
|
50
|
+
@actions_list = (@model_config.specified_actions_for_member.actions || []).select(&:member?)
|
51
|
+
elsif @abstract_model
|
52
|
+
@actions_list = (@model_config.specified_actions_for_collection.actions || []).select(&:collection?)
|
53
|
+
else
|
54
|
+
@actions_list = (RailsAdmin::Config.specified_actions || []).select(&:root?)
|
55
|
+
end
|
56
|
+
@actions_list.map! { |a| a.with({controller: self, object: @object, model: (@abstract_model and @abstract_model.model)}) }
|
57
|
+
|
58
|
+
if request.get? # Actions list
|
59
|
+
respond_to do |format|
|
60
|
+
format.html { render @action.template_name }
|
61
|
+
format.js { render @action.template_name, layout: false }
|
62
|
+
end
|
63
|
+
|
64
|
+
elsif request.post? # Do action
|
65
|
+
|
66
|
+
if (_action = @actions_list.find { |a| a.name == params[:specified_action][:name].to_sym })
|
67
|
+
if _action.args.blank?
|
68
|
+
args = {}
|
69
|
+
else
|
70
|
+
args = (params.require(:specified_action).require(:args).permit(_action.args.keys) || {})
|
71
|
+
end
|
72
|
+
begin
|
73
|
+
obj = @object || (@abstract_model and @abstract_model.model) || _action.object
|
74
|
+
@result = _action.process(obj, args)
|
75
|
+
@result = "Задача выполняется" if @result.is_a?(Thread)
|
76
|
+
@result ||= "Успешно!"
|
77
|
+
rescue Exception => ex
|
78
|
+
@error_message = _action.can_view_error_message ? ex.message : "Произошла ошибка ;("
|
79
|
+
@error_backtrace = ex.backtrace.join("\n") if _action.can_view_error_backtrace
|
80
|
+
end
|
81
|
+
respond_to do |format|
|
82
|
+
format.html {
|
83
|
+
# render @action.template_name
|
84
|
+
flash[:info] = "Попытка выполнения '#{_action.name}':"
|
85
|
+
flash[:success] = @result.to_s unless @error_message
|
86
|
+
flash[:error] = @error_message.to_s if @error_message
|
87
|
+
if @error_backtrace
|
88
|
+
flash[:alert] = "<button class='close show_hide' type='button'>⇕</button><pre>#{@error_backtrace}</pre>".html_safe
|
89
|
+
end
|
90
|
+
redirect_back(fallback_location: fallback_location)
|
91
|
+
}
|
92
|
+
format.js {
|
93
|
+
render json: {
|
94
|
+
result: (@error_message || @result).to_s,
|
95
|
+
error: {
|
96
|
+
message: @error_message.to_s,
|
97
|
+
backtrace: (@error_backtrace and "<button class='close show_hide' type='button'>⇕</button><pre>#{@error_backtrace}</pre>".html_safe)
|
98
|
+
}.compact
|
99
|
+
}
|
100
|
+
}
|
101
|
+
end
|
102
|
+
else
|
103
|
+
respond_to do |format|
|
104
|
+
format.html {
|
105
|
+
# render @action.template_name
|
106
|
+
flash[:error] = "Не найдено действия для выполнения"
|
107
|
+
redirect_back(fallback_location: fallback_location)
|
108
|
+
}
|
109
|
+
format.js {
|
110
|
+
render json: {
|
111
|
+
error: {
|
112
|
+
message: "Не найдено действия для выполнения"
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
register_instance_option :link_icon do
|
124
|
+
'fa fa-magic'
|
125
|
+
end
|
126
|
+
|
127
|
+
register_instance_option :statistics? do
|
128
|
+
false
|
129
|
+
end
|
130
|
+
|
131
|
+
register_instance_option :http_methods do
|
132
|
+
[:get, :post]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
module RailsAdmin
|
141
|
+
module Config
|
142
|
+
module Actions
|
143
|
+
class SpecifiedActionsForCollection < RailsAdmin::Config::Actions::SpecifiedActions
|
144
|
+
RailsAdmin::Config::Actions.register(self)
|
145
|
+
|
146
|
+
# Is the action acting on the root level (Example: /admin/contact)
|
147
|
+
register_instance_option :root? do
|
148
|
+
false
|
149
|
+
end
|
150
|
+
|
151
|
+
register_instance_option :collection? do
|
152
|
+
true
|
153
|
+
end
|
154
|
+
|
155
|
+
register_instance_option :member do
|
156
|
+
false
|
157
|
+
end
|
158
|
+
|
159
|
+
register_instance_option :route_fragment do
|
160
|
+
'specified_actions'
|
161
|
+
end
|
162
|
+
|
163
|
+
register_instance_option :template_name do
|
164
|
+
'specified_actions'
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
module RailsAdmin
|
174
|
+
module Config
|
175
|
+
module Actions
|
176
|
+
class SpecifiedActionsForMember < RailsAdmin::Config::Actions::SpecifiedActions
|
177
|
+
RailsAdmin::Config::Actions.register(self)
|
178
|
+
|
179
|
+
# Is the action acting on the root level (Example: /admin/contact)
|
180
|
+
register_instance_option :root? do
|
181
|
+
false
|
182
|
+
end
|
183
|
+
|
184
|
+
register_instance_option :collection? do
|
185
|
+
false
|
186
|
+
end
|
187
|
+
|
188
|
+
register_instance_option :member do
|
189
|
+
true
|
190
|
+
end
|
191
|
+
|
192
|
+
register_instance_option :route_fragment do
|
193
|
+
'specified_actions'
|
194
|
+
end
|
195
|
+
|
196
|
+
register_instance_option :template_name do
|
197
|
+
'specified_actions'
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module RailsAdminSpecifiedActions
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
|
4
|
+
initializer "RailsAdminSpecifiedActions precompile hook", group: :all do |app|
|
5
|
+
app.config.assets.precompile += %w(rails_admin/rails_admin_specified_actions.js rails_admin/rails_admin_specified_actions.css)
|
6
|
+
end
|
7
|
+
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
module RailsAdmin
|
2
|
+
module Config
|
3
|
+
# Provides accessors and autoregistering of model's fields.
|
4
|
+
module HasActions
|
5
|
+
# Defines a configuration for a field.
|
6
|
+
def action(name, target = nil, args = {}, add_to_section = true, &block)
|
7
|
+
action = _actions.detect { |a| name == a.name and (target.nil? or a.target == target) }
|
8
|
+
|
9
|
+
# some fields are hidden by default (belongs_to keys, has_many associations in list views.)
|
10
|
+
# unhide them if config specifically defines them
|
11
|
+
# if action
|
12
|
+
# action.show unless action.instance_variable_get("@#{action.name}_registered").is_a?(Proc)
|
13
|
+
# end
|
14
|
+
# Specify field as virtual if type is not specifically set and field was not
|
15
|
+
# found in default stack
|
16
|
+
|
17
|
+
if action.nil? && args == {}
|
18
|
+
action = (_actions << RailsAdminSpecifiedActions::SpecifiedAction.new(self, name, args)).last
|
19
|
+
else
|
20
|
+
if args && args != (action.nil? ? {} : action.args)
|
21
|
+
if action
|
22
|
+
# properties = action.properties
|
23
|
+
action = _actions[_actions.index(action)] = RailsAdminSpecifiedActions::SpecifiedAction.new(self, name, args)
|
24
|
+
else
|
25
|
+
action = (_actions << RailsAdminSpecifiedActions::SpecifiedAction.new(self, name, args)).last
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
if target
|
30
|
+
action.target do
|
31
|
+
target
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# If field has not been yet defined add some default properties
|
36
|
+
if add_to_section && !action.defined
|
37
|
+
action.defined = true
|
38
|
+
action.order = _actions.count(&:defined)
|
39
|
+
end
|
40
|
+
|
41
|
+
# If a block has been given evaluate it and sort fields after that
|
42
|
+
action.instance_eval(&block) if block
|
43
|
+
_actions
|
44
|
+
end
|
45
|
+
|
46
|
+
# configure a field without adding it.
|
47
|
+
def configure(name, type = nil, &block)
|
48
|
+
action(name, type, false, &block)
|
49
|
+
end
|
50
|
+
|
51
|
+
# include fields by name and apply an optionnal block to each (through a call to fields),
|
52
|
+
# or include fields by conditions if no field names
|
53
|
+
def include_actions(*action_names, &block)
|
54
|
+
if action_names.empty?
|
55
|
+
_actions.select { |a| a.instance_eval(&block) }.each do |a|
|
56
|
+
next if a.defined
|
57
|
+
a.defined = true
|
58
|
+
# a.order = _actions.count(&:defined)
|
59
|
+
end
|
60
|
+
else
|
61
|
+
actions(*action_names, &block)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# exclude fields by name or by condition (block)
|
66
|
+
def exclude_actions(*action_names, &block)
|
67
|
+
block ||= proc { |a| action_names.include?(a.name) }
|
68
|
+
_actions.each { |a| a.defined = true } if _actions.select(&:defined).empty?
|
69
|
+
_actions.select { |a| a.instance_eval(&block) }.each { |a| a.defined = false }
|
70
|
+
end
|
71
|
+
|
72
|
+
# API candy
|
73
|
+
alias_method :exclude_actions_if, :exclude_actions
|
74
|
+
alias_method :include_actions_if, :include_actions
|
75
|
+
|
76
|
+
def include_all_actions
|
77
|
+
include_actions_if { true }
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns all field configurations for the model configuration instance. If no fields
|
81
|
+
# have been defined returns all fields. Defined fields are sorted to match their
|
82
|
+
# order property. If order was not specified it will match the order in which fields
|
83
|
+
# were defined.
|
84
|
+
#
|
85
|
+
# If a block is passed it will be evaluated in the context of each field
|
86
|
+
def actions(*action_names, &block)
|
87
|
+
return all_actions if action_names.empty? && !block
|
88
|
+
|
89
|
+
if action_names.empty?
|
90
|
+
defined = _actions.select(&:defined)
|
91
|
+
defined = _actions if defined.empty?
|
92
|
+
else
|
93
|
+
defined = action_names.collect { |action_name| _actions.detect { |a| a.name == action_name } }
|
94
|
+
end
|
95
|
+
defined.collect do |a|
|
96
|
+
unless a.defined
|
97
|
+
a.defined = true
|
98
|
+
# a.order = _actions.count(&:defined)
|
99
|
+
end
|
100
|
+
a.instance_eval(&block) if block
|
101
|
+
a
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Defines configuration for fields by their type.
|
106
|
+
# def fields_of_type(type, &block)
|
107
|
+
# _fields.select { |f| type == f.type }.map! { |f| f.instance_eval(&block) } if block
|
108
|
+
# end
|
109
|
+
|
110
|
+
# Accessor for all fields
|
111
|
+
def all_actions
|
112
|
+
((ro_actions = _actions(true)).select(&:defined).presence || ro_actions).collect do |a|
|
113
|
+
# a.section = self
|
114
|
+
a
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Get all fields defined as visible, in the correct order.
|
119
|
+
def visible_actions
|
120
|
+
i = 0
|
121
|
+
# all_actions.collect { |a| a.with(bindings) }.select(&:visible?).sort_by { |a| [a.order, i += 1] } # stable sort, damn
|
122
|
+
all_actions.collect { |a| a.with(bindings) }.select(&:visible?)
|
123
|
+
end
|
124
|
+
|
125
|
+
# protected
|
126
|
+
|
127
|
+
# Raw fields.
|
128
|
+
# Recursively returns parent section's raw fields
|
129
|
+
# Duping it if accessed for modification.
|
130
|
+
def _actions(readonly = false)
|
131
|
+
return @_actions if @_actions
|
132
|
+
return @_ro_actions if readonly && @_ro_actions
|
133
|
+
|
134
|
+
if self.class == RailsAdmin::Config::Sections::Base
|
135
|
+
@_ro_actions = @_actions = [] #RailsAdmin::Config::Fields.factory(self)
|
136
|
+
else
|
137
|
+
# parent is RailsAdmin::Config::Model, recursion is on Section's classes
|
138
|
+
if respond_to?(:parent) and parent
|
139
|
+
@_ro_actions ||= [].freeze #parent.send(self.class.superclass.to_s.underscore.split('/').last)._actions(true).freeze
|
140
|
+
else
|
141
|
+
RailsAdmin::Config.specified_actions ||= []
|
142
|
+
@_ro_actions ||= RailsAdmin::Config.specified_actions
|
143
|
+
return readonly ? @_ro_actions : (RailsAdmin::Config.specified_actions ||= @_ro_actions.collect(&:clone))
|
144
|
+
end
|
145
|
+
end
|
146
|
+
readonly ? @_ro_actions : (@_actions ||= @_ro_actions.collect(&:clone))
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# require 'rails_admin/config/sections'
|
2
|
+
require 'rails_admin/config/sections/list'
|
3
|
+
require 'rails_admin_specified_actions/has_actions'
|
4
|
+
|
5
|
+
module RailsAdmin
|
6
|
+
module Config
|
7
|
+
module Sections
|
8
|
+
# Configuration of the explore view
|
9
|
+
class SpecifiedActions < Base
|
10
|
+
include RailsAdmin::Config::HasActions
|
11
|
+
end
|
12
|
+
class SpecifiedActionsForCollection < SpecifiedActions
|
13
|
+
end
|
14
|
+
class SpecifiedActionsForMember < SpecifiedActions
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
RailsAdmin::Config::Model.send :include, RailsAdmin::Config::Sections
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'rails_admin/config/proxyable'
|
2
|
+
require 'rails_admin/config/configurable'
|
3
|
+
class RailsAdminSpecifiedActions::SpecifiedAction
|
4
|
+
|
5
|
+
include RailsAdmin::Config::Proxyable
|
6
|
+
include RailsAdmin::Config::Configurable
|
7
|
+
|
8
|
+
attr_accessor :section, :defined, :order,
|
9
|
+
:abstract_model, :root, :parent,
|
10
|
+
:name
|
11
|
+
|
12
|
+
def initialize(_parent, _name, _args = {}, &block)
|
13
|
+
@parent = _parent
|
14
|
+
@root = _parent.root
|
15
|
+
@section = _parent
|
16
|
+
|
17
|
+
@abstract_model = parent.abstract_model unless parent.is_a?(RailsAdmin::Config::Actions::SpecifiedActions)
|
18
|
+
@defined = false
|
19
|
+
@name = _name.to_sym
|
20
|
+
args = _args || {}
|
21
|
+
@process_block = block
|
22
|
+
end
|
23
|
+
|
24
|
+
def root?
|
25
|
+
@root
|
26
|
+
# @parent.nil? or @parent == @root
|
27
|
+
# self.target == :root
|
28
|
+
end
|
29
|
+
def collection?
|
30
|
+
@parent.is_a? RailsAdmin::Config::Sections::SpecifiedActionsForCollection
|
31
|
+
# self.target == :collection
|
32
|
+
end
|
33
|
+
def member?
|
34
|
+
@parent.is_a? RailsAdmin::Config::Sections::SpecifiedActionsForMember
|
35
|
+
# self.target == :member
|
36
|
+
end
|
37
|
+
|
38
|
+
# private :do_process
|
39
|
+
def do_process(target, args)
|
40
|
+
if (_pb = self.process_block)
|
41
|
+
if _pb.respond_to?(:call)
|
42
|
+
begin
|
43
|
+
_pb.call(target, args)
|
44
|
+
rescue
|
45
|
+
_pb.call(target)
|
46
|
+
end
|
47
|
+
else
|
48
|
+
begin
|
49
|
+
target and target.try(_pb, args)
|
50
|
+
rescue
|
51
|
+
target and target.try(_pb)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
else
|
55
|
+
begin
|
56
|
+
target and target.try(@name, args)
|
57
|
+
rescue
|
58
|
+
target and target.try(@name)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def process(target, args)
|
65
|
+
return threaded_process(target, args) if self.threaded
|
66
|
+
do_process(target, args)
|
67
|
+
end
|
68
|
+
|
69
|
+
def threaded_process(target, args)
|
70
|
+
Thread.new(self, target, args) do |action, target, args|
|
71
|
+
action.do_process(target, args)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
register_instance_option :label do
|
76
|
+
name
|
77
|
+
end
|
78
|
+
|
79
|
+
register_instance_option :button_text do
|
80
|
+
name
|
81
|
+
end
|
82
|
+
|
83
|
+
register_instance_option :desc do
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
|
87
|
+
register_instance_option :visible? do
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
register_instance_option :can_view_error_backtrace do
|
92
|
+
cont = (bindings and bindings[:controller])
|
93
|
+
cu = (cont and cont._current_user)
|
94
|
+
if cu
|
95
|
+
if cont.respond_to?(:can?)
|
96
|
+
cont.can?(:view_error_backtrace, self)
|
97
|
+
elsif cu.respond_to?(:can_view_error_backtrace)
|
98
|
+
cu.can_view_error_backtrace
|
99
|
+
elsif cu.respond_to?(:admin?)
|
100
|
+
cu.admin?
|
101
|
+
end
|
102
|
+
else
|
103
|
+
false
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
register_instance_option :can_view_error_message do
|
108
|
+
cont = (bindings and bindings[:controller])
|
109
|
+
cu = (cont and cont._current_user)
|
110
|
+
if cu
|
111
|
+
if cont.respond_to?(:can?)
|
112
|
+
cont.can?(:view_error_message, self)
|
113
|
+
elsif cu.respond_to?(:can_view_error_message)
|
114
|
+
cu.can_view_error_message
|
115
|
+
elsif cu.respond_to?(:admin?)
|
116
|
+
cu.admin?
|
117
|
+
end
|
118
|
+
else
|
119
|
+
false
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
register_instance_option :process_block do
|
124
|
+
nil #true
|
125
|
+
end
|
126
|
+
|
127
|
+
register_instance_option :target do
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
|
131
|
+
register_instance_option :ajax do
|
132
|
+
false
|
133
|
+
end
|
134
|
+
|
135
|
+
register_instance_option :threaded do
|
136
|
+
false
|
137
|
+
end
|
138
|
+
|
139
|
+
register_instance_option :object do
|
140
|
+
nil
|
141
|
+
end
|
142
|
+
|
143
|
+
register_instance_option :args do
|
144
|
+
{}
|
145
|
+
end
|
146
|
+
|
147
|
+
register_instance_option :button_text do
|
148
|
+
'do'
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rails_admin_specified_actions/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rails_admin_specified_actions"
|
8
|
+
spec.version = RailsAdminSpecifiedActions::VERSION
|
9
|
+
spec.authors = ["Alexander Kiseliev"]
|
10
|
+
spec.email = ["dev@redrocks.pro"]
|
11
|
+
|
12
|
+
spec.summary = %q{custom actions for rails_admin}
|
13
|
+
spec.description = %q{custom actions for rails_admin}
|
14
|
+
spec.homepage = "https://github.com/red-rocks/rails_admin_specified_actions"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
# if spec.respond_to?(:metadata)
|
19
|
+
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
20
|
+
# else
|
21
|
+
# raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
22
|
+
# end
|
23
|
+
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
spec.bindir = "exe"
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler"
|
30
|
+
spec.add_development_dependency "rake"
|
31
|
+
spec.add_dependency "rails_admin", ">= 0.8.1"
|
32
|
+
end
|
data/release.sh
ADDED
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails_admin_specified_actions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1.rc1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Kiseliev
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-04-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rails_admin
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.8.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.8.1
|
55
|
+
description: custom actions for rails_admin
|
56
|
+
email:
|
57
|
+
- dev@redrocks.pro
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- app/assets/javascripts/rails_admin/rails_admin_specified_actions.coffee
|
67
|
+
- app/assets/stylesheets/rails_admin/rails_admin_specified_actions.sass
|
68
|
+
- app/views/rails_admin/main/_specified_actions_list.html.slim
|
69
|
+
- app/views/rails_admin/main/specified_actions.html.slim
|
70
|
+
- bin/console
|
71
|
+
- bin/setup
|
72
|
+
- config/locales/specific_actions.en.yml
|
73
|
+
- config/locales/specific_actions.ru.yml
|
74
|
+
- lib/rails_admin_specified_actions.rb
|
75
|
+
- lib/rails_admin_specified_actions/action.rb
|
76
|
+
- lib/rails_admin_specified_actions/engine.rb
|
77
|
+
- lib/rails_admin_specified_actions/has_actions.rb
|
78
|
+
- lib/rails_admin_specified_actions/rails_admin_patch.rb
|
79
|
+
- lib/rails_admin_specified_actions/section.rb
|
80
|
+
- lib/rails_admin_specified_actions/specified_action.rb
|
81
|
+
- lib/rails_admin_specified_actions/version.rb
|
82
|
+
- rails_admin_specified_actions.gemspec
|
83
|
+
- release.sh
|
84
|
+
homepage: https://github.com/red-rocks/rails_admin_specified_actions
|
85
|
+
licenses: []
|
86
|
+
metadata: {}
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 1.3.1
|
101
|
+
requirements: []
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 2.7.9
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: custom actions for rails_admin
|
107
|
+
test_files: []
|