rails-add_ons 2.1.1 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -0
- data/app/assets/javascripts/rails/add_ons/application/acts-as-list.js.coffee +21 -0
- data/app/assets/javascripts/rails/add_ons/application.js +0 -2
- data/app/components/component/collection_table.rb +26 -2
- data/app/components/component/resource_table.rb +7 -1
- data/app/concerns/component/collection_table/acts_as_list_concern.rb +16 -0
- data/app/concerns/component/collection_table/acts_as_published_concern.rb +10 -0
- data/app/concerns/component/collection_table/batch_actions_concern.rb +12 -0
- data/app/concerns/component/collection_table/boolean_concern.rb +10 -0
- data/app/concerns/component/resource_table/boolean_concern.rb +10 -0
- data/app/concerns/resources_controller/acts_as_list_concern.rb +32 -0
- data/app/concerns/resources_controller/acts_as_published_concern.rb +73 -0
- data/app/concerns/resources_controller/awesome_nested_set_concern.rb +31 -0
- data/app/concerns/resources_controller/batch_actions_concern.rb +16 -0
- data/app/concerns/resources_controller/friendly_id_concern.rb +15 -0
- data/app/concerns/resources_controller/kaminari.rb +13 -11
- data/app/concerns/resources_controller/location_history.rb +31 -26
- data/app/concerns/resources_controller/pagination.rb +13 -11
- data/app/concerns/resources_controller/resource_inflections.rb +13 -11
- data/app/concerns/resources_controller/resources.rb +9 -7
- data/app/concerns/resources_controller/rest_actions.rb +77 -73
- data/app/concerns/resources_controller/rest_resource_urls.rb +25 -23
- data/app/concerns/resources_controller/sorting.rb +22 -14
- data/app/concerns/resources_controller/will_paginate.rb +14 -12
- data/app/concerns/service_controller/rest_actions.rb +15 -0
- data/app/helpers/rails/add_ons/table_helper.rb +10 -0
- data/app/views/component/_collection_table.haml +13 -12
- data/app/views/component/table/body_cells/_acts_as_list.haml +11 -0
- data/app/views/component/table/body_cells/_acts_as_published.haml +9 -0
- data/app/views/component/table/body_cells/_association.haml +5 -1
- data/app/views/component/table/body_cells/_batch_actions.haml +1 -0
- data/app/views/component/table/body_cells/_boolean.haml +4 -0
- data/app/views/component/table/header_cells/_batch_actions.haml +42 -0
- data/config/locales/de.yml +30 -1
- data/config/locales/en.yml +4 -1
- data/lib/generators/rails/add_ons/install_generator.rb +15 -0
- data/lib/generators/rails/add_ons/resources_controller_spec_generator.rb +53 -0
- data/lib/generators/rails/add_ons/templates/initializer.rb +7 -0
- data/lib/generators/rails/add_ons/templates/spec.rb +53 -0
- data/lib/rails/add_ons/configuration.rb +11 -0
- data/lib/rails/add_ons/shoulda/matchers/implement_create_action_matcher.rb +36 -4
- data/lib/rails/add_ons/shoulda/matchers/implement_update_action_matcher.rb +60 -17
- data/lib/rails/add_ons/version.rb +1 -1
- data/lib/rails/add_ons.rb +3 -2
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bcd8208bf74f48898936baa02d21720ba62ccf8
|
4
|
+
data.tar.gz: c7225749ed3871555682fa94e556394b392d6d9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a287305c63b7cb4bb325c91ec7daa497f29adf5a3a6ae67ab79ed7381614ae20c593616a8c1830bf0055628fe9d8f65e84fa322aead5c412523fe5339bd2769
|
7
|
+
data.tar.gz: 966da1755681d98edcb0ca1445a6579fa210dd3dc9f82c5e5a304184be8b864f2b31163d81340c31e84a307461dca9388ed06182801f6d7eee0a28ad184bf6a2
|
data/README.md
CHANGED
@@ -24,6 +24,10 @@ to your applications javascript include file, as it was removed.
|
|
24
24
|
|
25
25
|
ServiceController::Base now uses the verbs new and create instead of invoke and call. Furthermore @resource is dropped in favor of @service. Please modify your controllers and views and routing accordingly.
|
26
26
|
|
27
|
+
### Update path to 2.2.0
|
28
|
+
|
29
|
+
Jquery and JQuery UJS are not automatically required anymore. You need to require it yourself.
|
30
|
+
|
27
31
|
## Installation
|
28
32
|
Add this line to your application's Gemfile:
|
29
33
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$ ->
|
2
|
+
$('[data-acts-as-list-item]').each ->
|
3
|
+
$(@).draggable({
|
4
|
+
scope: $(@).attr('data-acts-as-list-item-scope'),
|
5
|
+
revert: true
|
6
|
+
})
|
7
|
+
|
8
|
+
$ ->
|
9
|
+
$('[data-acts-as-list-item]').each ->
|
10
|
+
redirect_target = $(@).attr('data-acts-as-list-item-on-drop-target')
|
11
|
+
authenticity_token = $( 'meta[name="csrf-token"]' ).attr( 'content' );
|
12
|
+
|
13
|
+
$(@).droppable({
|
14
|
+
accept: '.acts-as-list-item',
|
15
|
+
scope: $(@).attr('data-acts-as-list-item-scope'),
|
16
|
+
activeClass: 'btn-success',
|
17
|
+
drop: (event, ui) ->
|
18
|
+
dropped_element = $(ui.draggable)
|
19
|
+
dropped_element_to_param = dropped_element.attr('data-acts-as-list-item-uid')
|
20
|
+
$.redirect(redirect_target,{ authenticity_token: authenticity_token, dropped_id: dropped_element_to_param });
|
21
|
+
})
|
@@ -1,6 +1,19 @@
|
|
1
1
|
module Component
|
2
|
+
# Example:
|
3
|
+
#
|
4
|
+
# = collection_table(collection: @posts, resource_class: Post) do |t|
|
5
|
+
# = t.column :id, sort: true
|
6
|
+
# = t.column :title
|
7
|
+
# = t.column :body
|
8
|
+
# = t.boolean :visible
|
9
|
+
# = t.timestamps format: :short
|
10
|
+
#
|
2
11
|
class CollectionTable < Base
|
3
12
|
include AwesomeNestedSetConcern
|
13
|
+
include ActsAsPublishedConcern
|
14
|
+
include ActsAsListConcern
|
15
|
+
include BatchActionsConcern
|
16
|
+
include BooleanConcern
|
4
17
|
|
5
18
|
SIZE_MAP = {
|
6
19
|
default: nil,
|
@@ -9,6 +22,8 @@ module Component
|
|
9
22
|
|
10
23
|
def initialize(*args)
|
11
24
|
super
|
25
|
+
@options.reverse_merge!(header: true)
|
26
|
+
|
12
27
|
@columns = {}
|
13
28
|
@collection = @options.delete(:collection)
|
14
29
|
@resource_class = @options.delete(:resource_class) || @collection.first.class
|
@@ -20,8 +35,12 @@ module Component
|
|
20
35
|
@columns[name] = options
|
21
36
|
end
|
22
37
|
|
38
|
+
def id(options = {}, &block)
|
39
|
+
column(:id, options, &block)
|
40
|
+
end
|
41
|
+
|
23
42
|
def timestamp(name, options = {}, &block)
|
24
|
-
options.reverse_merge!(render_as: :timestamp, format:
|
43
|
+
options.reverse_merge!(render_as: :timestamp, format: Rails::AddOns::Configuration.table_default_timestamp_format)
|
25
44
|
column(name, options, &block)
|
26
45
|
end
|
27
46
|
|
@@ -46,10 +65,15 @@ module Component
|
|
46
65
|
columns: @columns,
|
47
66
|
collection: @collection,
|
48
67
|
resource_class: @resource_class,
|
49
|
-
table_css_classes: table_css_classes
|
68
|
+
table_css_classes: table_css_classes,
|
69
|
+
show_header: show_header
|
50
70
|
}
|
51
71
|
end
|
52
72
|
|
73
|
+
def show_header
|
74
|
+
!!@options[:header]
|
75
|
+
end
|
76
|
+
|
53
77
|
def striped?
|
54
78
|
!!@options[:striped]
|
55
79
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Component
|
2
2
|
class ResourceTable < Base
|
3
|
+
include BooleanConcern
|
4
|
+
|
3
5
|
attr_reader :resource
|
4
6
|
|
5
7
|
def initialize(*args)
|
@@ -15,8 +17,12 @@ module Component
|
|
15
17
|
@rows[name] = options
|
16
18
|
end
|
17
19
|
|
20
|
+
def id(options = {}, &block)
|
21
|
+
row(:id, options, &block)
|
22
|
+
end
|
23
|
+
|
18
24
|
def timestamp(name, options = {}, &block)
|
19
|
-
options.reverse_merge!(render_as: :timestamp, format:
|
25
|
+
options.reverse_merge!(render_as: :timestamp, format: Rails::AddOns::Configuration.table_default_timestamp_format)
|
20
26
|
row(name, options, &block)
|
21
27
|
end
|
22
28
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Component
|
2
|
+
module CollectionTable::ActsAsListConcern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def acts_as_list_actions(options = {}, &block)
|
6
|
+
options.reverse_merge!(render_as: :acts_as_list, title: t('.column_titles.acts_as_list'), scope: nil)
|
7
|
+
|
8
|
+
scope = options.delete(:scope)
|
9
|
+
scope = "#{scope}_id".intern if scope.is_a?(Symbol) && scope.to_s !~ /_id$/
|
10
|
+
|
11
|
+
options.merge(scope: scope)
|
12
|
+
|
13
|
+
column(:acts_as_list_actions, options, &block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Component
|
2
|
+
module CollectionTable::ActsAsPublishedConcern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def acts_as_published_actions(options = {}, &block)
|
6
|
+
options.reverse_merge!(render_as: :acts_as_published, title: t('.column_titles.acts_as_published'))
|
7
|
+
column(:acts_as_published_actions, options, &block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Component
|
2
|
+
module CollectionTable::BatchActionsConcern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def batch_actions(options = {}, &block)
|
6
|
+
@wrap_in_form = true
|
7
|
+
title = @view.render partial: 'component/table/header_cells/batch_actions', locals: { options: options }
|
8
|
+
options.reverse_merge!(render_as: :batch_actions, title: title)
|
9
|
+
column(:batch_actions, options, &block)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ResourcesController
|
2
|
+
module ActsAsListConcern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def reposition
|
6
|
+
@resource = load_resource
|
7
|
+
@dropped_resource = load_resource_scope.find(params[:dropped_id])
|
8
|
+
@dropped_resource.set_list_position(@resource.position)
|
9
|
+
position = @dropped_resource.position < @resource.position ? :before : :after
|
10
|
+
|
11
|
+
label_methods = [:human, :name, :title, :email, :to_s]
|
12
|
+
|
13
|
+
target_resource_label = nil
|
14
|
+
label_methods.each do |method_name|
|
15
|
+
if @resource.respond_to?(method_name)
|
16
|
+
target_resource_label = @resource.send(method_name)
|
17
|
+
break
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
inserted_resource_label = nil
|
22
|
+
label_methods.each do |method_name|
|
23
|
+
if @dropped_resource.respond_to?(method_name)
|
24
|
+
inserted_resource_label = @dropped_resource.send(method_name)
|
25
|
+
break
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
redirect_to collection_path, notice: I18n.t("acts_as_list.flash.actions.reposition.inserted_#{position}", target_resource: target_resource_label, inserted_resource: inserted_resource_label)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module ResourcesController
|
2
|
+
module ActsAsPublishedConcern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def publish_many
|
6
|
+
@collection = load_collection_scope.find(params[:ids])
|
7
|
+
@collection.map(&:publish!)
|
8
|
+
|
9
|
+
resource_labels = []
|
10
|
+
@collection.each do |resource|
|
11
|
+
[:human, :name, :title, :email, :to_s].each do |method_name|
|
12
|
+
if resource.respond_to?(method_name)
|
13
|
+
resource_labels << resource.send(method_name)
|
14
|
+
break
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
notice = I18n.t("acts_as_published.notices.published_many", names: resource_labels.to_sentence)
|
20
|
+
if Rails.version < '5.0.0'
|
21
|
+
redirect_to :back, notice: notice
|
22
|
+
else
|
23
|
+
flash[:notice] = notice
|
24
|
+
redirect_back(fallback_location: main_app.root_path)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def unpublish_many
|
29
|
+
@collection = load_collection_scope.find(params[:ids])
|
30
|
+
@collection.map(&:unpublish!)
|
31
|
+
|
32
|
+
resource_labels = []
|
33
|
+
@collection.each do |resource|
|
34
|
+
[:human, :name, :title, :email, :to_s].each do |method_name|
|
35
|
+
if resource.respond_to?(method_name)
|
36
|
+
resource_labels << resource.send(method_name)
|
37
|
+
break
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
notice = I18n.t("acts_as_published.notices.unpublished_many", names: resource_labels.to_sentence)
|
43
|
+
if Rails.version < '5.0.0'
|
44
|
+
redirect_to :back, notice: notice
|
45
|
+
else
|
46
|
+
flash[:notice] = notice
|
47
|
+
redirect_back(fallback_location: main_app.root_path)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def toggle_published
|
52
|
+
@resource = load_resource
|
53
|
+
@resource.toggle_published!
|
54
|
+
|
55
|
+
action_taken = @resource.published? ? 'published' : 'unpublished'
|
56
|
+
|
57
|
+
resource_label = nil
|
58
|
+
[:human, :name, :title, :email, :to_s].each do |method_name|
|
59
|
+
if @resource.respond_to?(method_name)
|
60
|
+
resource_label = @resource.send(method_name)
|
61
|
+
break
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
if Rails.version < '5.0.0'
|
66
|
+
redirect_to :back, notice: I18n.t("acts_as_published.notices.#{action_taken}", name: resource_label)
|
67
|
+
else
|
68
|
+
flash[:notice] = I18n.t("acts_as_published.notices.#{action_taken}", name: resource_label)
|
69
|
+
redirect_back(fallback_location: main_app.root_path)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ResourcesController
|
2
|
+
module AwesomeNestedSetConcern
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def reposition
|
6
|
+
@resource = load_resource
|
7
|
+
@dropped_resource = resource_class.find(params[:dropped_id])
|
8
|
+
@dropped_resource.move_to_right_of(@resource)
|
9
|
+
|
10
|
+
label_methods = [:human, :name, :email, :to_s]
|
11
|
+
|
12
|
+
target_resource_label = nil
|
13
|
+
label_methods.each do |method_name|
|
14
|
+
if @resource.respond_to?(method_name)
|
15
|
+
target_resource_label = @resource.send(method_name)
|
16
|
+
break
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
inserted_resource_label = nil
|
21
|
+
label_methods.each do |method_name|
|
22
|
+
if @dropped_resource.respond_to?(method_name)
|
23
|
+
inserted_resource_label = @dropped_resource.send(method_name)
|
24
|
+
break
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
redirect_to collection_path, notice: I18n.t("awesome_nested_set.flash.actions.reposition.notice", target_resource: target_resource_label, inserted_resource: inserted_resource_label)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ResourcesController
|
2
|
+
module BatchActionsConcern
|
3
|
+
def destroy_many
|
4
|
+
@collection = load_collection_scope.where(id: params[:ids])
|
5
|
+
@collection.destroy_all
|
6
|
+
|
7
|
+
respond_with @collection, location: after_destroy_many_location, noticse: t('.success')
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def after_destroy_many_location
|
13
|
+
collection_path
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,15 +1,17 @@
|
|
1
|
-
module ResourcesController
|
2
|
-
|
3
|
-
base
|
4
|
-
|
1
|
+
module ResourcesController
|
2
|
+
module Kaminari
|
3
|
+
def self.included(base)
|
4
|
+
base.helper_method :paginate?
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
def paginate?
|
8
|
+
true
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
+
private
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
def load_collection
|
14
|
+
@collection = load_collection_scope.page(params[:page])
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end
|
17
|
+
end
|
@@ -1,36 +1,41 @@
|
|
1
|
-
module ResourcesController
|
2
|
-
|
1
|
+
module ResourcesController
|
2
|
+
module LocationHistory
|
3
|
+
extend ActiveSupport::Concern
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
included do
|
6
|
+
if respond_to?(:before_action)
|
7
|
+
before_action :store_location
|
8
|
+
else
|
9
|
+
before_filter :store_location
|
10
|
+
end
|
11
|
+
|
12
|
+
helper_method :last_location
|
9
13
|
end
|
10
|
-
end
|
11
14
|
|
12
|
-
|
15
|
+
private
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
def store_location
|
18
|
+
return if request.referer.nil?
|
19
|
+
truncate_location_history(9)
|
20
|
+
location_history[Time.zone.now] = request.referer
|
21
|
+
end
|
18
22
|
|
19
|
-
|
20
|
-
|
21
|
-
|
23
|
+
def location_history
|
24
|
+
session[:location_history] ||= {}
|
25
|
+
end
|
22
26
|
|
23
|
-
|
24
|
-
|
25
|
-
|
27
|
+
def last_location
|
28
|
+
location_history.sort.last.try(:last)
|
29
|
+
end
|
26
30
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
def truncate_location_history(count = 0)
|
32
|
+
return if location_history.size <= count
|
33
|
+
truncated = session[:location_history].sort.last(count)
|
34
|
+
session[:location_history] = if truncated.respond_to?(:to_h)
|
35
|
+
truncated.to_h
|
36
|
+
else
|
37
|
+
truncated.each_with_object({}) { |a, hash| hash[a.first] = a.last }
|
38
|
+
end
|
34
39
|
end
|
35
40
|
end
|
36
41
|
end
|
@@ -1,15 +1,17 @@
|
|
1
|
-
module ResourcesController
|
2
|
-
|
3
|
-
base
|
4
|
-
|
1
|
+
module ResourcesController
|
2
|
+
module Pagination
|
3
|
+
def self.included(base)
|
4
|
+
base.helper_method :paginate?
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
def paginate?
|
8
|
+
true
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
+
private
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
def load_collection
|
14
|
+
@collection = load_collection_scope.page(params[:page])
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end
|
17
|
+
end
|
@@ -1,16 +1,18 @@
|
|
1
|
-
module ResourcesController
|
2
|
-
|
1
|
+
module ResourcesController
|
2
|
+
module ResourceInflections
|
3
|
+
extend ActiveSupport::Concern
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
included do
|
6
|
+
helper_method :inflections
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def inflections
|
12
|
+
{
|
13
|
+
resource_name: resource_class.model_name.human(count: 1),
|
14
|
+
collection_name: resource_class.model_name.human(count: 2)
|
15
|
+
}
|
16
|
+
end
|
15
17
|
end
|
16
18
|
end
|
@@ -1,11 +1,13 @@
|
|
1
|
-
module ResourcesController
|
2
|
-
|
1
|
+
module ResourcesController
|
2
|
+
module Resources
|
3
|
+
extend ActiveSupport::Concern
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
included do
|
6
|
+
helper_method :resource_class
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
def resource_class
|
10
|
+
self.class.resource_class
|
11
|
+
end
|
10
12
|
end
|
11
13
|
end
|