active_action 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/.gitignore +8 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +175 -0
- data/LICENSE +21 -0
- data/README.md +132 -0
- data/Rakefile +12 -0
- data/activeaction.gemspec +39 -0
- data/lib/active_action/action.rb +12 -0
- data/lib/active_action/action_controller.rb +60 -0
- data/lib/active_action/bootstrap_dropdown.rb +38 -0
- data/lib/active_action/renderer.rb +3 -0
- data/lib/active_action/version.rb +3 -0
- data/lib/active_action/view_helpers.rb +22 -0
- data/lib/active_action.rb +17 -0
- metadata +185 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: d0c193e9af085271835f1bb36f124cfc4c4fbe39
|
|
4
|
+
data.tar.gz: e958b93e568c9d1a9fb89494a7c3799f0b7a46e9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 2f85875f402d3ad99957e251532c5d2becfde702acc1b3b78cfd4ec28d81c7872d7425ce8c736643f216c120e479d9473a9334f14d9b5af9b83b355d1a6a4b10
|
|
7
|
+
data.tar.gz: fb5c45d2cd1ed2785bfbd465450893c7a6d85b1f9052eefe23e0483dd142a8b1d3d09266c3a560fb61c4b6ac6f035e713d5091bd82e1d16cefddf05a0d0d0e9e
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
active_action (0.1.0)
|
|
5
|
+
rails (>= 3.0)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
actioncable (5.2.3)
|
|
11
|
+
actionpack (= 5.2.3)
|
|
12
|
+
nio4r (~> 2.0)
|
|
13
|
+
websocket-driver (>= 0.6.1)
|
|
14
|
+
actionmailer (5.2.3)
|
|
15
|
+
actionpack (= 5.2.3)
|
|
16
|
+
actionview (= 5.2.3)
|
|
17
|
+
activejob (= 5.2.3)
|
|
18
|
+
mail (~> 2.5, >= 2.5.4)
|
|
19
|
+
rails-dom-testing (~> 2.0)
|
|
20
|
+
actionpack (5.2.3)
|
|
21
|
+
actionview (= 5.2.3)
|
|
22
|
+
activesupport (= 5.2.3)
|
|
23
|
+
rack (~> 2.0)
|
|
24
|
+
rack-test (>= 0.6.3)
|
|
25
|
+
rails-dom-testing (~> 2.0)
|
|
26
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
27
|
+
actionview (5.2.3)
|
|
28
|
+
activesupport (= 5.2.3)
|
|
29
|
+
builder (~> 3.1)
|
|
30
|
+
erubi (~> 1.4)
|
|
31
|
+
rails-dom-testing (~> 2.0)
|
|
32
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
33
|
+
activejob (5.2.3)
|
|
34
|
+
activesupport (= 5.2.3)
|
|
35
|
+
globalid (>= 0.3.6)
|
|
36
|
+
activemodel (5.2.3)
|
|
37
|
+
activesupport (= 5.2.3)
|
|
38
|
+
activerecord (5.2.3)
|
|
39
|
+
activemodel (= 5.2.3)
|
|
40
|
+
activesupport (= 5.2.3)
|
|
41
|
+
arel (>= 9.0)
|
|
42
|
+
activestorage (5.2.3)
|
|
43
|
+
actionpack (= 5.2.3)
|
|
44
|
+
activerecord (= 5.2.3)
|
|
45
|
+
marcel (~> 0.3.1)
|
|
46
|
+
activesupport (5.2.3)
|
|
47
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
48
|
+
i18n (>= 0.7, < 2)
|
|
49
|
+
minitest (~> 5.1)
|
|
50
|
+
tzinfo (~> 1.1)
|
|
51
|
+
addressable (2.6.0)
|
|
52
|
+
public_suffix (>= 2.0.2, < 4.0)
|
|
53
|
+
arel (9.0.0)
|
|
54
|
+
ast (2.4.0)
|
|
55
|
+
builder (3.2.3)
|
|
56
|
+
capybara (3.18.0)
|
|
57
|
+
addressable
|
|
58
|
+
mini_mime (>= 0.1.3)
|
|
59
|
+
nokogiri (~> 1.8)
|
|
60
|
+
rack (>= 1.6.0)
|
|
61
|
+
rack-test (>= 0.6.3)
|
|
62
|
+
regexp_parser (~> 1.2)
|
|
63
|
+
xpath (~> 3.2)
|
|
64
|
+
concurrent-ruby (1.1.5)
|
|
65
|
+
crass (1.0.4)
|
|
66
|
+
docile (1.3.1)
|
|
67
|
+
erubi (1.8.0)
|
|
68
|
+
globalid (0.4.2)
|
|
69
|
+
activesupport (>= 4.2.0)
|
|
70
|
+
i18n (1.6.0)
|
|
71
|
+
concurrent-ruby (~> 1.0)
|
|
72
|
+
jaro_winkler (1.5.2)
|
|
73
|
+
json (2.2.0)
|
|
74
|
+
loofah (2.2.3)
|
|
75
|
+
crass (~> 1.0.2)
|
|
76
|
+
nokogiri (>= 1.5.9)
|
|
77
|
+
mail (2.7.1)
|
|
78
|
+
mini_mime (>= 0.1.1)
|
|
79
|
+
marcel (0.3.3)
|
|
80
|
+
mimemagic (~> 0.3.2)
|
|
81
|
+
metaclass (0.0.4)
|
|
82
|
+
method_source (0.9.2)
|
|
83
|
+
mimemagic (0.3.3)
|
|
84
|
+
mini_mime (1.0.1)
|
|
85
|
+
mini_portile2 (2.4.0)
|
|
86
|
+
minitest (5.11.3)
|
|
87
|
+
minitest-rails (3.0.0)
|
|
88
|
+
minitest (~> 5.8)
|
|
89
|
+
railties (~> 5.0)
|
|
90
|
+
mocha (1.8.0)
|
|
91
|
+
metaclass (~> 0.0.1)
|
|
92
|
+
nio4r (2.3.1)
|
|
93
|
+
nokogiri (1.10.3)
|
|
94
|
+
mini_portile2 (~> 2.4.0)
|
|
95
|
+
parallel (1.17.0)
|
|
96
|
+
parser (2.6.3.0)
|
|
97
|
+
ast (~> 2.4.0)
|
|
98
|
+
public_suffix (3.0.3)
|
|
99
|
+
rack (2.0.7)
|
|
100
|
+
rack-test (1.1.0)
|
|
101
|
+
rack (>= 1.0, < 3)
|
|
102
|
+
rails (5.2.3)
|
|
103
|
+
actioncable (= 5.2.3)
|
|
104
|
+
actionmailer (= 5.2.3)
|
|
105
|
+
actionpack (= 5.2.3)
|
|
106
|
+
actionview (= 5.2.3)
|
|
107
|
+
activejob (= 5.2.3)
|
|
108
|
+
activemodel (= 5.2.3)
|
|
109
|
+
activerecord (= 5.2.3)
|
|
110
|
+
activestorage (= 5.2.3)
|
|
111
|
+
activesupport (= 5.2.3)
|
|
112
|
+
bundler (>= 1.3.0)
|
|
113
|
+
railties (= 5.2.3)
|
|
114
|
+
sprockets-rails (>= 2.0.0)
|
|
115
|
+
rails-dom-testing (2.0.3)
|
|
116
|
+
activesupport (>= 4.2.0)
|
|
117
|
+
nokogiri (>= 1.6)
|
|
118
|
+
rails-html-sanitizer (1.0.4)
|
|
119
|
+
loofah (~> 2.2, >= 2.2.2)
|
|
120
|
+
railties (5.2.3)
|
|
121
|
+
actionpack (= 5.2.3)
|
|
122
|
+
activesupport (= 5.2.3)
|
|
123
|
+
method_source
|
|
124
|
+
rake (>= 0.8.7)
|
|
125
|
+
thor (>= 0.19.0, < 2.0)
|
|
126
|
+
rainbow (3.0.0)
|
|
127
|
+
rake (10.5.0)
|
|
128
|
+
regexp_parser (1.4.0)
|
|
129
|
+
rubocop (0.68.1)
|
|
130
|
+
jaro_winkler (~> 1.5.1)
|
|
131
|
+
parallel (~> 1.10)
|
|
132
|
+
parser (>= 2.5, != 2.5.1.1)
|
|
133
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
134
|
+
ruby-progressbar (~> 1.7)
|
|
135
|
+
unicode-display_width (>= 1.4.0, < 1.6)
|
|
136
|
+
ruby-progressbar (1.10.0)
|
|
137
|
+
simplecov (0.16.1)
|
|
138
|
+
docile (~> 1.1)
|
|
139
|
+
json (>= 1.8, < 3)
|
|
140
|
+
simplecov-html (~> 0.10.0)
|
|
141
|
+
simplecov-html (0.10.2)
|
|
142
|
+
sprockets (3.7.2)
|
|
143
|
+
concurrent-ruby (~> 1.0)
|
|
144
|
+
rack (> 1, < 3)
|
|
145
|
+
sprockets-rails (3.2.1)
|
|
146
|
+
actionpack (>= 4.0)
|
|
147
|
+
activesupport (>= 4.0)
|
|
148
|
+
sprockets (>= 3.0.0)
|
|
149
|
+
thor (0.20.3)
|
|
150
|
+
thread_safe (0.3.6)
|
|
151
|
+
tzinfo (1.2.5)
|
|
152
|
+
thread_safe (~> 0.1)
|
|
153
|
+
unicode-display_width (1.5.0)
|
|
154
|
+
websocket-driver (0.7.0)
|
|
155
|
+
websocket-extensions (>= 0.1.0)
|
|
156
|
+
websocket-extensions (0.1.3)
|
|
157
|
+
xpath (3.2.0)
|
|
158
|
+
nokogiri (~> 1.8)
|
|
159
|
+
|
|
160
|
+
PLATFORMS
|
|
161
|
+
ruby
|
|
162
|
+
|
|
163
|
+
DEPENDENCIES
|
|
164
|
+
active_action!
|
|
165
|
+
bundler (~> 1.16)
|
|
166
|
+
capybara
|
|
167
|
+
minitest-rails
|
|
168
|
+
mocha
|
|
169
|
+
rails (>= 5.1.6)
|
|
170
|
+
rake (~> 10.0)
|
|
171
|
+
rubocop
|
|
172
|
+
simplecov
|
|
173
|
+
|
|
174
|
+
BUNDLED WITH
|
|
175
|
+
1.16.6
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 Josh Brody
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# ActiveAction
|
|
2
|
+
|
|
3
|
+
An elegant DSL to define batch actions in your Rails controllers and display them in your views.
|
|
4
|
+
|
|
5
|
+
## Idea
|
|
6
|
+
|
|
7
|
+
The idea of ActiveAction is to use a form object to submit the form, but changing the action you submit to — as chosen by the user in your batch actions selection.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add this line to your application's Gemfile:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem 'active_action'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
And then execute:
|
|
18
|
+
|
|
19
|
+
$ bundle
|
|
20
|
+
|
|
21
|
+
And restart your Rails server.
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
Use the `active_action :route, options = {}` DSL to define a batch action.
|
|
26
|
+
|
|
27
|
+
Then build your batch action dropdown with `active_actions.each { ... }` in your view.
|
|
28
|
+
|
|
29
|
+
## Step-by-step
|
|
30
|
+
|
|
31
|
+
### Controller
|
|
32
|
+
|
|
33
|
+
Define your actions.
|
|
34
|
+
|
|
35
|
+
class NotificationsController < ApplicationController
|
|
36
|
+
active_action :mark_as_read, label: "Mark selected as read"
|
|
37
|
+
|
|
38
|
+
def mark_as_read
|
|
39
|
+
notifications = Notification.find(params[:collection_ids])
|
|
40
|
+
notifications.update_all(read: true)
|
|
41
|
+
redirect_to notifications_path, notice: "Marked as read"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
### View
|
|
46
|
+
|
|
47
|
+
Wrap your ActiveRecord collection (or whatever collection) into a form object. Then, drop in a button to handle the batch actions you defined in your controller.
|
|
48
|
+
|
|
49
|
+
```erbruby
|
|
50
|
+
<%= simple_form_for :notifications do |f| %>
|
|
51
|
+
<div class="dropdown">
|
|
52
|
+
<a class="btn btn-secondary dropdown-toggle active_actions_button" disabled="disabled" href="#" id="activeActionsButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Actions</a>
|
|
53
|
+
<div class="dropdown-menu" aria-labelled-by="activeActionsButton">
|
|
54
|
+
<% active_actions_for(:all).each do |action| %>
|
|
55
|
+
<a class="dropdown-item active_action" href="javascript:;" data-action="<%= action.path %>"><%= action.label %></a>
|
|
56
|
+
<% end %>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
<table>
|
|
60
|
+
<thead>
|
|
61
|
+
<tr>
|
|
62
|
+
<td></td>
|
|
63
|
+
<td>Content</td>
|
|
64
|
+
</tr>
|
|
65
|
+
</thead>
|
|
66
|
+
<tbody>
|
|
67
|
+
<% @notifications.each do |notification| %>
|
|
68
|
+
<tr>
|
|
69
|
+
<td><input type="checkbox" name="collection_ids[]" value=<%= notification.id %>" /></td>
|
|
70
|
+
<td><%= notification.content %></td>
|
|
71
|
+
</tr>
|
|
72
|
+
<% end %>
|
|
73
|
+
</tbody>
|
|
74
|
+
</table>
|
|
75
|
+
<% end %>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### And some Javascript
|
|
79
|
+
|
|
80
|
+
Lastly, drop in some Javascript to handle changing the form action.
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
$('.active_action').on('click', function() {
|
|
84
|
+
var form = $(this).closest('form');
|
|
85
|
+
form.attr('action', form.attr('action') + "/" + $(this).attr('data-action'));
|
|
86
|
+
form.submit();
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Frequently asked questions
|
|
91
|
+
|
|
92
|
+
### I want to submit to a member route. What does my view look like?
|
|
93
|
+
|
|
94
|
+
Just change what the form submits to. More info with examples here.
|
|
95
|
+
|
|
96
|
+
```erbruby
|
|
97
|
+
<%= simple_form_for @restaurant do |f| %>
|
|
98
|
+
<%= active_actions_button_for(:beers) %>
|
|
99
|
+
<table>
|
|
100
|
+
<thead>
|
|
101
|
+
<tr>
|
|
102
|
+
<td></td>
|
|
103
|
+
<td>Beer name</td>
|
|
104
|
+
</tr>
|
|
105
|
+
</thead>
|
|
106
|
+
<tbody>
|
|
107
|
+
<% @resetaurant.beers.each do |beer| %>
|
|
108
|
+
<tr>
|
|
109
|
+
<td><input type="checkbox" name="collection_ids[]" value=<%= beer.id %>" /></td>
|
|
110
|
+
<td><%= beer.name %></td>
|
|
111
|
+
</tr>
|
|
112
|
+
<% end %>
|
|
113
|
+
</tbody>
|
|
114
|
+
</table>
|
|
115
|
+
<% end %>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Frequently asked questions
|
|
119
|
+
|
|
120
|
+
### Does this come with javascript to handle select-all-ish functionality?
|
|
121
|
+
|
|
122
|
+
Nope. [But you can use what I've been using for my projects](https://github.com/joshmn/active_action/wiki/Drop-in-javascript-for-your-tables).
|
|
123
|
+
|
|
124
|
+
### What's a scope?
|
|
125
|
+
|
|
126
|
+
A scope merely defines what context a active action is relevant to inside its controller. Say you had `RestaurantsController` and you wanted to "Mark as visited" (for `:restaurants`), or for their beers selection (presumably on your `restaurants#show` view), "Mark [beer] as consumed" for `:beers`. You could define these as separate scopes for your active actions array.
|
|
127
|
+
|
|
128
|
+
Defaults to `:all`.
|
|
129
|
+
|
|
130
|
+
### Why don't you just d—
|
|
131
|
+
|
|
132
|
+
Because I loathe javascript.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
+
require "active_action/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "active_action"
|
|
7
|
+
spec.version = ActiveAction::VERSION
|
|
8
|
+
spec.authors = ["Josh Brody"]
|
|
9
|
+
spec.email = ["josh@josh.mn"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "A tidy DSL to express batch actions"
|
|
12
|
+
spec.description = "A tidy DSL to express batch actions"
|
|
13
|
+
spec.homepage = "https://github.com/joshmn/activeaction"
|
|
14
|
+
|
|
15
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
16
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
17
|
+
if spec.respond_to?(:metadata)
|
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
19
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
20
|
+
else
|
|
21
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
|
22
|
+
"public gem pushes."
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
27
|
+
end
|
|
28
|
+
spec.require_paths = ["lib"]
|
|
29
|
+
|
|
30
|
+
spec.add_dependency 'rails', '>= 3.0'
|
|
31
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
|
32
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
33
|
+
spec.add_development_dependency 'rails', '>= 5.1.6'
|
|
34
|
+
spec.add_development_dependency 'capybara'
|
|
35
|
+
spec.add_development_dependency 'simplecov'
|
|
36
|
+
spec.add_development_dependency 'rubocop'
|
|
37
|
+
spec.add_development_dependency 'minitest-rails'
|
|
38
|
+
spec.add_development_dependency 'mocha'
|
|
39
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module ActiveAction
|
|
2
|
+
class Action
|
|
3
|
+
attr_reader :action, :label, :scopes, :path
|
|
4
|
+
def initialize(action, options = {})
|
|
5
|
+
options.assert_valid_keys(:scope, :label, :path, :scopes)
|
|
6
|
+
@action = action
|
|
7
|
+
@label = options[:label] || @action.to_s
|
|
8
|
+
@scopes = options[:scopes] || Array.wrap(options[:scope] || :all)
|
|
9
|
+
@path = (options[:path] || @action).to_s
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module ActiveAction
|
|
2
|
+
module ActionController
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
extend ClassMethods
|
|
7
|
+
include InstanceMethods
|
|
8
|
+
helper HelperMethods
|
|
9
|
+
helper_method :active_actions
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module ClassMethods
|
|
13
|
+
# Rails generates CSRF tokens on a per-form basis.
|
|
14
|
+
# This means things will break when you change the action.
|
|
15
|
+
#
|
|
16
|
+
# See https://github.com/rails/rails/pull/22275 for more info.
|
|
17
|
+
def active_action(action_name, options = {})
|
|
18
|
+
protect_from_forgery except: action_name
|
|
19
|
+
add_active_action(action_name, options)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def add_active_action(action_name, options = {})
|
|
23
|
+
options = normalize_active_action_options(action_name, options)
|
|
24
|
+
_active_actions << ActiveAction::Action.new(action_name, options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def normalize_active_action_options(action_name, options)
|
|
28
|
+
options[:label] ||= action_name.to_s.titleize
|
|
29
|
+
options[:scopes] ||= []
|
|
30
|
+
options[:scopes] += (Array.wrap(options[:scope]))
|
|
31
|
+
if options[:scopes].empty?
|
|
32
|
+
options[:scopes] << :all
|
|
33
|
+
end
|
|
34
|
+
options[:scopes].map!(&:to_sym)
|
|
35
|
+
options[:path] ||= action_name
|
|
36
|
+
options
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def _active_actions
|
|
40
|
+
@_active_actions ||= []
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
module InstanceMethods
|
|
45
|
+
def active_actions
|
|
46
|
+
self.class._active_actions
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
module HelperMethods
|
|
51
|
+
# Finds collection_actions for the specified `scopes`
|
|
52
|
+
def active_actions_for(*scopes)
|
|
53
|
+
scopes = Array.wrap(scopes.presence || :all)
|
|
54
|
+
active_actions.select do |ca|
|
|
55
|
+
(scopes & ca.scopes).any?
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module ActiveAction
|
|
2
|
+
class BootstrapDropdown < Renderer
|
|
3
|
+
def self.to_html(label:, actions:)
|
|
4
|
+
new(label: label, actions: actions).to_html
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
attr_reader :label, :actions
|
|
8
|
+
def initialize(label:, actions:)
|
|
9
|
+
@label = label
|
|
10
|
+
@actions = actions
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_html
|
|
14
|
+
capture do
|
|
15
|
+
content_tag(:div, class: "dropdown") do
|
|
16
|
+
concat dropdown_tag(label)
|
|
17
|
+
concat dropdown_for(actions)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def dropdown_tag(label)
|
|
25
|
+
content_tag(:a, class: "btn btn-secondary dropdown-toggle active_actions_button", disabled: :disabled, href: "#", id: "activeActionsButton", data: { toggle: "dropdown" }, aria: { haspopup: 'true', expanded: 'false' }) do
|
|
26
|
+
label
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def dropdown_for(actions)
|
|
31
|
+
content_tag(:div, class: "dropdown-menu", 'aria-labelled-by': "activeActionsButton") do
|
|
32
|
+
actions.each do |act|
|
|
33
|
+
concat content_tag(:a, class: "dropdown-item active_action", href: "javascript:;", data: { action: act.path }) { act.label }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module ActiveAction
|
|
2
|
+
module ViewHelpers
|
|
3
|
+
NO_ACTIVE_ACTIONS_MESSAGE = "<!-- No active actions found. -->"
|
|
4
|
+
DEFAULT_LABEL = "Active actions"
|
|
5
|
+
|
|
6
|
+
def active_selection_tag(value, checked = false, options = {})
|
|
7
|
+
check_box_tag 'collection_ids[]', value, checked, {class: 'active_actions_selection'}.merge(options)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def active_actions_button(label)
|
|
11
|
+
active_actions_button_for(:all, label: label)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def active_actions_button_for(scopes = [:all], label: DEFAULT_LABEL, renderer: BootstrapDropdown)
|
|
15
|
+
actions = active_actions_for(scopes)
|
|
16
|
+
if actions.empty?
|
|
17
|
+
return NO_ACTIVE_ACTIONS_MESSAGE.html_safe
|
|
18
|
+
end
|
|
19
|
+
renderer.to_html(label: label, actions: actions)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'action_controller'
|
|
2
|
+
require 'rails/railtie'
|
|
3
|
+
require 'active_action/action_controller'
|
|
4
|
+
require 'active_action/renderer'
|
|
5
|
+
require 'active_action/bootstrap_dropdown'
|
|
6
|
+
require 'active_action/action'
|
|
7
|
+
require 'active_action/view_helpers'
|
|
8
|
+
|
|
9
|
+
module ActiveAction
|
|
10
|
+
class Engine < Rails::Railtie
|
|
11
|
+
initializer 'activeaction.controller' do
|
|
12
|
+
ActiveSupport.on_load(:action_controller) do
|
|
13
|
+
::ActionController::Base.send(:include, ActiveAction::ActionController)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: active_action
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Josh Brody
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2019-05-04 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rails
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '3.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '3.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: bundler
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '1.16'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '1.16'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '10.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '10.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rails
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 5.1.6
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 5.1.6
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: capybara
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: simplecov
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rubocop
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: minitest-rails
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: mocha
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
description: A tidy DSL to express batch actions
|
|
140
|
+
email:
|
|
141
|
+
- josh@josh.mn
|
|
142
|
+
executables: []
|
|
143
|
+
extensions: []
|
|
144
|
+
extra_rdoc_files: []
|
|
145
|
+
files:
|
|
146
|
+
- ".gitignore"
|
|
147
|
+
- Gemfile
|
|
148
|
+
- Gemfile.lock
|
|
149
|
+
- LICENSE
|
|
150
|
+
- README.md
|
|
151
|
+
- Rakefile
|
|
152
|
+
- activeaction.gemspec
|
|
153
|
+
- lib/active_action.rb
|
|
154
|
+
- lib/active_action/action.rb
|
|
155
|
+
- lib/active_action/action_controller.rb
|
|
156
|
+
- lib/active_action/bootstrap_dropdown.rb
|
|
157
|
+
- lib/active_action/renderer.rb
|
|
158
|
+
- lib/active_action/version.rb
|
|
159
|
+
- lib/active_action/view_helpers.rb
|
|
160
|
+
homepage: https://github.com/joshmn/activeaction
|
|
161
|
+
licenses: []
|
|
162
|
+
metadata:
|
|
163
|
+
homepage_uri: https://github.com/joshmn/activeaction
|
|
164
|
+
source_code_uri: https://github.com/joshmn/activeaction
|
|
165
|
+
post_install_message:
|
|
166
|
+
rdoc_options: []
|
|
167
|
+
require_paths:
|
|
168
|
+
- lib
|
|
169
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - ">="
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '0'
|
|
174
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
|
+
requirements:
|
|
176
|
+
- - ">="
|
|
177
|
+
- !ruby/object:Gem::Version
|
|
178
|
+
version: '0'
|
|
179
|
+
requirements: []
|
|
180
|
+
rubyforge_project:
|
|
181
|
+
rubygems_version: 2.6.13
|
|
182
|
+
signing_key:
|
|
183
|
+
specification_version: 4
|
|
184
|
+
summary: A tidy DSL to express batch actions
|
|
185
|
+
test_files: []
|