rails-add_ons 2.1.1 → 2.2.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 +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
|