rails-add_ons 2.2.1 → 3.0.0.pre1
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/app/assets/javascripts/rails/add_ons/application/autosubmit.js.coffee +4 -0
- data/app/assets/stylesheets/rails/add_ons/application/{bootstrap_overrides.scss → bootstrap_overrides.css} +0 -0
- data/app/assets/stylesheets/rails/add_ons/application/{table_monospaced.scss → table_monospaced.css} +0 -0
- data/app/assets/stylesheets/rails/add_ons/application/{widgets.scss → widgets.css} +0 -0
- data/app/assets/stylesheets/rails/add_ons/application.css +3 -0
- data/app/assets/stylesheets/rails/add_ons/{bootstrap_v3_flex_extension.scss → bootstrap_v3_flex_extension.css} +0 -0
- data/app/components/component/collection_table.rb +4 -0
- data/app/concerns/component/collection_table/batch_actions_concern.rb +4 -0
- data/app/concerns/controller/autosubmit_concern.rb +48 -0
- data/app/concerns/controller/query_conditions.rb +18 -1
- data/app/concerns/resources_controller/acts_as_list_concern.rb +7 -1
- data/app/concerns/resources_controller/batch_actions_concern.rb +9 -2
- data/app/concerns/resources_controller/location_history.rb +1 -0
- data/app/concerns/resources_controller/rest_actions.rb +4 -3
- data/app/concerns/resources_controller/search_form_concern.rb +9 -0
- data/app/concerns/resources_controller/will_paginate.rb +16 -2
- data/app/concerns/service_controller/rest_actions.rb +1 -1
- data/app/controllers/api/resources_controller/base.rb +1 -1
- data/app/controllers/api/service_controller/base.rb +1 -1
- data/app/controllers/resources_controller/base.rb +1 -1
- data/app/controllers/service_controller/base.rb +1 -1
- data/app/helpers/rails/add_ons/autosubmit_helper.rb +11 -0
- data/app/helpers/rails/add_ons/search_form_helper.rb +103 -0
- data/app/parsers/api/resources_controller/condition_parser.rb +62 -16
- data/app/views/component/table/header_cells/_batch_actions.haml +1 -1
- data/app/views/service_controller/base/_form_errors.haml +2 -1
- data/config/locales/de.yml +17 -0
- data/lib/generators/rails/add_ons/templates/initializer.rb +24 -0
- data/lib/rails/add_ons/configuration.rb +5 -1
- data/lib/rails/add_ons/shoulda/matchers/implement_create_action_matcher.rb +12 -6
- data/lib/rails/add_ons/shoulda/matchers/implement_delete_action_matcher.rb +12 -6
- data/lib/rails/add_ons/shoulda/matchers/implement_index_action_matcher.rb +13 -6
- data/lib/rails/add_ons/shoulda/matchers/implement_show_action_matcher.rb +15 -10
- data/lib/rails/add_ons/shoulda/matchers/implement_update_action_matcher.rb +12 -6
- data/lib/rails/add_ons/version.rb +1 -1
- metadata +28 -9
- data/app/assets/stylesheets/rails/add_ons/application.scss +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbbb783440b059a3b92ea129bd2f842870974373
|
4
|
+
data.tar.gz: caee54825a95a1bb70770ca526d967a8178c09c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cd22f3de8861299824bb3c9fbf377f8b9a920c6a71db291774f6a36bb5a514eaf72a1ec8eb112a6f33e77e40ac7177545edf7f5b7d16e3d72f817925eaec15f
|
7
|
+
data.tar.gz: 3ec98bb46404d2dc7d356ec2b7cec645cdbb87f481cf020a9c5c968ebc1f5fc1d6c8c72ef68e9312b5d74c3665fc0e6a0e9f7a357685c97d0c8657c2e5ff5aee
|
File without changes
|
data/app/assets/stylesheets/rails/add_ons/application/{table_monospaced.scss → table_monospaced.css}
RENAMED
File without changes
|
File without changes
|
File without changes
|
@@ -49,6 +49,10 @@ module Component
|
|
49
49
|
timestamp(:updated_at, options)
|
50
50
|
end
|
51
51
|
|
52
|
+
# Example:
|
53
|
+
#
|
54
|
+
# = table.association :category, sortable: true, label_method: :name, link_to: ->(r) { url_for(r.category) }
|
55
|
+
#
|
52
56
|
def association(name, options = {}, &block)
|
53
57
|
options.reverse_merge!(render_as: :association)
|
54
58
|
column(name, options, &block)
|
@@ -2,6 +2,10 @@ module Component
|
|
2
2
|
module CollectionTable::BatchActionsConcern
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
+
# Example:
|
6
|
+
#
|
7
|
+
# = table.batch_actions(actions: { destroy: url_for(action: :destroy_many) })
|
8
|
+
#
|
5
9
|
def batch_actions(options = {}, &block)
|
6
10
|
@wrap_in_form = true
|
7
11
|
title = @view.render partial: 'component/table/header_cells/batch_actions', locals: { options: options }
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Controller
|
2
|
+
# Handles automatic form submits.
|
3
|
+
#
|
4
|
+
# Prerequisites:
|
5
|
+
#
|
6
|
+
# Include the javascript:
|
7
|
+
#
|
8
|
+
# # app/assets/javascripts/application.js
|
9
|
+
# //= require rails/add_ons/application/autosubmit
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# # app/controllers/posts_controller.rb
|
14
|
+
# class PostsController < ApplicationController
|
15
|
+
# include AutosubmitConcern
|
16
|
+
#
|
17
|
+
# # ...
|
18
|
+
#
|
19
|
+
# private
|
20
|
+
#
|
21
|
+
# def autosubmit?
|
22
|
+
# true
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # app/views/posts/new.html.haml
|
27
|
+
# = form_for(...) do |f|
|
28
|
+
# = autosubmit
|
29
|
+
#
|
30
|
+
module AutosubmitConcern
|
31
|
+
extend ActiveSupport::Concern
|
32
|
+
|
33
|
+
included do
|
34
|
+
helper Rails::AddOns::AutosubmitHelper
|
35
|
+
helper_method :autosubmit?, :autosubmit_now?
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def autosubmit?
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
def autosubmit_now?
|
45
|
+
autosubmit? && action_name == 'new'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -2,7 +2,13 @@ module Controller::QueryConditions
|
|
2
2
|
private
|
3
3
|
|
4
4
|
def add_conditions_from_query(scope)
|
5
|
-
query_params.
|
5
|
+
if query_params.keys.include?('q')
|
6
|
+
condition_params = normalize_query_params(query_params)
|
7
|
+
else
|
8
|
+
condition_params = query_params
|
9
|
+
end
|
10
|
+
|
11
|
+
condition_params.reject.reject { |k,v| v.blank? }.each do |field, condition|
|
6
12
|
case field
|
7
13
|
when 'limit'
|
8
14
|
scope = scope.limit(condition.to_i)
|
@@ -31,4 +37,15 @@ module Controller::QueryConditions
|
|
31
37
|
def default_query_params_exceptions
|
32
38
|
%w(sort_by sort_direction utf8 commit page)
|
33
39
|
end
|
40
|
+
|
41
|
+
def normalize_query_params(params)
|
42
|
+
params['q'].each_with_object({}) { |(k, v), m| m[normalize_key(k)] = v }
|
43
|
+
end
|
44
|
+
|
45
|
+
def normalize_key(key)
|
46
|
+
splitted_key = key.split('_')
|
47
|
+
predicate = splitted_key.last
|
48
|
+
attribute = splitted_key[0..-2].join('_')
|
49
|
+
"#{attribute}(#{predicate})"
|
50
|
+
end
|
34
51
|
end
|
@@ -26,7 +26,13 @@ module ResourcesController
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
redirect_to
|
29
|
+
redirect_to after_reposition_location, notice: I18n.t("acts_as_list.flash.actions.reposition.inserted_#{position}", target_resource: target_resource_label, inserted_resource: inserted_resource_label)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def after_reposition_location
|
35
|
+
collection_path
|
30
36
|
end
|
31
37
|
end
|
32
38
|
end
|
@@ -1,10 +1,17 @@
|
|
1
1
|
module ResourcesController
|
2
|
+
# Don't forget to add routes:
|
3
|
+
#
|
4
|
+
# # config/routes.rb;
|
5
|
+
# resources :users do
|
6
|
+
# post :destroy_many, on: :collection
|
7
|
+
# end
|
8
|
+
#
|
2
9
|
module BatchActionsConcern
|
3
10
|
def destroy_many
|
4
11
|
@collection = load_collection_scope.where(id: params[:ids])
|
5
12
|
@collection.destroy_all
|
6
13
|
|
7
|
-
respond_with @collection, location: after_destroy_many_location,
|
14
|
+
respond_with @collection, location: after_destroy_many_location, notice: t('.success')
|
8
15
|
end
|
9
16
|
|
10
17
|
private
|
@@ -13,4 +20,4 @@ module ResourcesController
|
|
13
20
|
collection_path
|
14
21
|
end
|
15
22
|
end
|
16
|
-
end
|
23
|
+
end
|
@@ -13,6 +13,7 @@ module ResourcesController
|
|
13
13
|
before_action :load_resource, only: [:show, :edit, :destroy, :update]
|
14
14
|
before_action :initialize_resource, only: [:new]
|
15
15
|
before_action :initialize_resource_for_create, only: [:create]
|
16
|
+
before_action :before_rest_action, if: -> { respond_to?(:before_rest_action, true) }
|
16
17
|
else
|
17
18
|
before_filter :load_collection, only: [:index]
|
18
19
|
before_filter :load_resource, only: [:show, :edit, :destroy, :update]
|
@@ -27,7 +28,7 @@ module ResourcesController
|
|
27
28
|
def edit; end
|
28
29
|
|
29
30
|
def update
|
30
|
-
if @resource.send(update_method_name, permitted_params) && respond_to?(:after_update_location, true)
|
31
|
+
if @resource.send(update_method_name, permitted_params) && respond_to?(:after_update_location, true) && after_update_location.present?
|
31
32
|
respond_with(respond_with_namespace, @resource, location: after_update_location)
|
32
33
|
else
|
33
34
|
respond_with(respond_with_namespace, @resource)
|
@@ -36,7 +37,7 @@ module ResourcesController
|
|
36
37
|
|
37
38
|
def destroy
|
38
39
|
@resource.destroy
|
39
|
-
if respond_to?(:after_destroy_location, true)
|
40
|
+
if respond_to?(:after_destroy_location, true) && after_destroy_location.present?
|
40
41
|
respond_with(respond_with_namespace, @resource, location: after_destroy_location)
|
41
42
|
else
|
42
43
|
respond_with(respond_with_namespace, @resource)
|
@@ -44,7 +45,7 @@ module ResourcesController
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def create
|
47
|
-
if @resource.save && respond_to?(:after_create_location, true)
|
48
|
+
if @resource.save && respond_to?(:after_create_location, true) && after_create_location.present?
|
48
49
|
respond_with(respond_with_namespace, @resource, location: after_create_location)
|
49
50
|
else
|
50
51
|
respond_with(respond_with_namespace, @resource)
|
@@ -1,4 +1,16 @@
|
|
1
1
|
module ResourcesController
|
2
|
+
# Setting the pagination size in the controller:
|
3
|
+
#
|
4
|
+
# # app/controllers/posts_controller.rb
|
5
|
+
# class PostsController < ApplicationController
|
6
|
+
# # ...
|
7
|
+
# private
|
8
|
+
#
|
9
|
+
# def per_page
|
10
|
+
# 15
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
#
|
2
14
|
module WillPaginate
|
3
15
|
extend ActiveSupport::Concern
|
4
16
|
|
@@ -13,7 +25,9 @@ module ResourcesController
|
|
13
25
|
private
|
14
26
|
|
15
27
|
def load_collection
|
16
|
-
|
28
|
+
options = { page: params[:page] }
|
29
|
+
options[:per_page] = per_page if respond_to?(:per_page, true)
|
30
|
+
@collection = load_collection_scope.paginate(options)
|
17
31
|
end
|
18
32
|
end
|
19
|
-
end
|
33
|
+
end
|
@@ -26,7 +26,7 @@ module ServiceController::RestActions
|
|
26
26
|
@result = execute_service
|
27
27
|
if @result.success?
|
28
28
|
|
29
|
-
if respond_to?(:after_success_location, true)
|
29
|
+
if respond_to?(:after_success_location, true) && after_success_location.present?
|
30
30
|
redirect_to(after_success_location, notice: success_message)
|
31
31
|
else
|
32
32
|
flash.now[:success] = success_message
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Rails
|
2
|
+
module AddOns
|
3
|
+
module SearchFormHelper
|
4
|
+
# Example:
|
5
|
+
#
|
6
|
+
# = search_form_for(@collection, url: collection_path, method: :get) do |f|
|
7
|
+
# = f.input :title_cont
|
8
|
+
# = f.input :product_number_cont
|
9
|
+
# = f.boolean :active_eq
|
10
|
+
# = f.submit nil, class: 'btn btn-primary'
|
11
|
+
# = f.reset nil, class: 'btn btn-default'
|
12
|
+
#
|
13
|
+
def search_form_for(collection, options = {}, &block)
|
14
|
+
wrapped_collection = SearchableCollection.new(collection, params[:q])
|
15
|
+
simple_form_for(wrapped_collection, options.reverse_merge(as: :q, url: collection_path, method: :get, builder: SearchFormBuilder), &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
class SearchFormBuilder < SimpleForm::FormBuilder
|
19
|
+
def boolean(name, options = {})
|
20
|
+
translated_label = translate_label_for_boolean(name)
|
21
|
+
options.reverse_merge!(collection: [[I18n.t("search_form_builder.yes"), 1], [I18n.t("search_form_builder.no"), 0]], include_blank: true, label: translated_label)
|
22
|
+
input name, options
|
23
|
+
end
|
24
|
+
|
25
|
+
def input(name, options = {})
|
26
|
+
if association = options.delete(:association)
|
27
|
+
translated_label = translate_label(name, association)
|
28
|
+
input_name = "#{association}.#{name}"
|
29
|
+
else
|
30
|
+
translated_label = translate_label(name)
|
31
|
+
input_name = name
|
32
|
+
end
|
33
|
+
super(input_name, options.reverse_merge(label: translated_label))
|
34
|
+
end
|
35
|
+
|
36
|
+
def submit(title = nil, options = {})
|
37
|
+
title ||= I18n.t('search_form_builder.submit')
|
38
|
+
super(title, options)
|
39
|
+
end
|
40
|
+
|
41
|
+
def reset(title = nil, options = {})
|
42
|
+
title ||= I18n.t('search_form_builder.reset')
|
43
|
+
link_html = options.delete(:link_html) || {}
|
44
|
+
template.link_to(title, template.url_for(), link_html)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def translate_label(name, association = nil)
|
50
|
+
splitted_name = name.to_s.split('_')
|
51
|
+
attribute_name = splitted_name[0..-2].join('_')
|
52
|
+
predicate = splitted_name.last
|
53
|
+
if association.nil?
|
54
|
+
klass_name = object.original_model_class_name
|
55
|
+
else
|
56
|
+
klass_name = object.original_model_class.reflect_on_association(association).klass.name
|
57
|
+
end
|
58
|
+
translated_attribute_name = klass_name.constantize.human_attribute_name(attribute_name)
|
59
|
+
I18n.t("search_form_builder.predicates.#{predicate}", attribute_name: translated_attribute_name)
|
60
|
+
end
|
61
|
+
|
62
|
+
def translate_label_for_boolean(name)
|
63
|
+
splitted_name = name.to_s.split('_')
|
64
|
+
attribute_name = splitted_name[0..-2].join('_')
|
65
|
+
predicate = splitted_name.last
|
66
|
+
if association.nil?
|
67
|
+
klass_name = object.original_model_class_name
|
68
|
+
else
|
69
|
+
klass_name = object.original_model_class.reflect_on_association(association).klass
|
70
|
+
end
|
71
|
+
translated_attribute_name = klass_name.constantize.human_attribute_name(attribute_name)
|
72
|
+
I18n.t("search_form_builder.boolean_label", attribute_name: translated_attribute_name)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class SearchableCollection
|
77
|
+
include ActiveModel::Model
|
78
|
+
extend ActiveModel::Translation
|
79
|
+
|
80
|
+
def method_missing(method, *args)
|
81
|
+
if method.to_s.match(/(.+)_(gt|gt_or_eq|eq|not_eq|lt_or_eq|lt|null|not_null|cont)/)
|
82
|
+
@query.send(:[], method)
|
83
|
+
else
|
84
|
+
super
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def initialize(collection, query)
|
89
|
+
@collection = collection
|
90
|
+
@query = query || {}
|
91
|
+
end
|
92
|
+
|
93
|
+
def original_model_class_name
|
94
|
+
@collection.class.to_s.deconstantize
|
95
|
+
end
|
96
|
+
|
97
|
+
def original_model_class
|
98
|
+
@collection.klass
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -9,7 +9,8 @@ module Api
|
|
9
9
|
lt_or_eq: :<=,
|
10
10
|
lt: :<,
|
11
11
|
null: :is_null,
|
12
|
-
not_null: :is_not_null
|
12
|
+
not_null: :is_not_null,
|
13
|
+
cont: :like
|
13
14
|
}
|
14
15
|
|
15
16
|
def initialize(scope, field, condition)
|
@@ -24,13 +25,19 @@ module Api
|
|
24
25
|
|
25
26
|
def build_condition_statement(parent_key, condition, nested = false)
|
26
27
|
if is_a_condition?(parent_key) && !nested
|
27
|
-
column, operator =
|
28
|
+
table, column, operator = extract_table_column_and_operator(parent_key)
|
28
29
|
return handle_null_condition(column, operator) if is_null_operator?(operator)
|
29
|
-
|
30
|
-
|
30
|
+
# binding.pry
|
31
|
+
if operator == 'cont'
|
32
|
+
return ["#{table}.#{column} LIKE ?", "%#{normalized_condition(table, column, condition)}%"]
|
31
33
|
else
|
32
|
-
["#{column} = ?", condition]
|
34
|
+
return ["#{table}.#{column} = ?", normalized_condition(table, column, condition)]
|
33
35
|
end
|
36
|
+
# if column_is_boolean?(column)
|
37
|
+
# ["#{column} = ?", to_boolean(condition)]
|
38
|
+
# else
|
39
|
+
# ["#{column} = ?", condition]
|
40
|
+
# end
|
34
41
|
else
|
35
42
|
if nested
|
36
43
|
column = extract_column(parent_key)
|
@@ -70,9 +77,23 @@ module Api
|
|
70
77
|
obj.to_s.split("(").first
|
71
78
|
end
|
72
79
|
|
73
|
-
def extract_column_and_operator(string)
|
80
|
+
# def extract_column_and_operator(string)
|
81
|
+
# if string =~ /([\.a-z_]{1,})\(([a-z_]{2,})\)/
|
82
|
+
# return $~[1], $~[2]
|
83
|
+
# end
|
84
|
+
# end
|
85
|
+
|
86
|
+
def extract_table_column_and_operator(string)
|
74
87
|
if string =~ /([\.a-z_]{1,})\(([a-z_]{2,})\)/
|
75
|
-
|
88
|
+
table_and_column = $~[1]
|
89
|
+
operator = $~[2]
|
90
|
+
column, table_or_association = table_and_column.split('.').reverse
|
91
|
+
if table_or_association.nil?
|
92
|
+
table = @scope.table_name
|
93
|
+
else
|
94
|
+
table = tables_and_classes_with_associations[table_or_association].table_name
|
95
|
+
end
|
96
|
+
return table, column, operator
|
76
97
|
end
|
77
98
|
end
|
78
99
|
|
@@ -80,23 +101,48 @@ module Api
|
|
80
101
|
OPERATOR_MAP
|
81
102
|
end
|
82
103
|
|
83
|
-
def column_is_boolean?(column_name)
|
84
|
-
scope, column = get_scope_and_column_from_column_name(column_name)
|
104
|
+
def column_is_boolean?(table_name, column_name)
|
105
|
+
scope, column = get_scope_and_column_from_column_name(column_name, table_name)
|
106
|
+
raise "Unknown column: #{column_name}" unless scope.columns_hash.has_key?(column)
|
85
107
|
scope.columns_hash[column].type == :boolean
|
86
108
|
end
|
87
109
|
|
88
|
-
def get_scope_and_column_from_column_name(column_name)
|
89
|
-
if
|
90
|
-
tables_and_classes = @scope.reflect_on_all_associations.each_with_object({}) { |a, memo| memo[a.table_name] = a.klass }
|
91
|
-
scope = tables_and_classes[$~[1]]
|
92
|
-
return scope, $~[2]
|
93
|
-
else
|
110
|
+
def get_scope_and_column_from_column_name(column_name, table_name = nil)
|
111
|
+
if table_name == @scope.table_name
|
94
112
|
return @scope, column_name
|
113
|
+
else
|
114
|
+
# tables_and_classes = @scope.reflect_on_all_associations.reject { |a| a.polymorphic? }.each_with_object({}) { |a, memo| memo[a.table_name] = a.klass }
|
115
|
+
# associations_and_classes = @scope.reflect_on_all_associations.reject { |a| a.polymorphic? }.each_with_object({}) { |a, memo| memo[a.name.to_s] = a.klass }
|
116
|
+
# scope = tables_and_classes.merge(associations_and_classes)[$~[1]]
|
117
|
+
scope = tables_and_classes_with_associations[table_name]
|
118
|
+
return scope, column_name
|
95
119
|
end
|
96
120
|
end
|
97
121
|
|
122
|
+
def tables_and_classes_with_associations
|
123
|
+
tables_and_classes = @scope.reflect_on_all_associations.reject { |a| (a.respond_to?(:polymorphic?) && a.polymorphic?) || a.options[:polymorphic] == true }.each_with_object({}) { |a, memo| memo[a.table_name] = a.klass }
|
124
|
+
associations_and_classes = @scope.reflect_on_all_associations.reject { |a| (a.respond_to?(:polymorphic?) && a.polymorphic?) || a.options[:polymorphic] == true }.each_with_object({}) { |a, memo| memo[a.name.to_s] = a.klass }
|
125
|
+
tables_and_classes.merge(associations_and_classes)
|
126
|
+
end
|
127
|
+
|
98
128
|
def to_boolean(string)
|
99
|
-
|
129
|
+
result = case
|
130
|
+
when Rails.version < '4.2'
|
131
|
+
::ActiveRecord::ConnectionAdapters::Column.value_to_boolean(string)
|
132
|
+
when Rails.version < '5.0'
|
133
|
+
::ActiveRecord::Type::Boolean.new.type_cast_for_schema(string)
|
134
|
+
else
|
135
|
+
::ActiveRecord::Type::Boolean.new.cast(string)
|
136
|
+
end
|
137
|
+
result.gsub('"', '')
|
138
|
+
end
|
139
|
+
|
140
|
+
def normalized_condition(table, column, condition)
|
141
|
+
if column_is_boolean?(table, column)
|
142
|
+
to_boolean(condition)
|
143
|
+
else
|
144
|
+
condition
|
145
|
+
end
|
100
146
|
end
|
101
147
|
end
|
102
148
|
end
|
@@ -7,7 +7,7 @@
|
|
7
7
|
= hidden_field_tag :authenticity_token, form_authenticity_token
|
8
8
|
.dropdown.batch-action-dropdown
|
9
9
|
%button.btn.btn-default.dropdown-toggle{"aria-expanded" => "true", "aria-haspopup" => "true", "data-toggle" => "dropdown", :type => "button", id: 'batch-action-dropdown' }
|
10
|
-
= t('.
|
10
|
+
= t('.title')
|
11
11
|
%span.caret
|
12
12
|
%ul.dropdown-menu{"aria-labelledby" => 'batch-action-dropdown' }
|
13
13
|
- options[:actions].each do |action, target|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
- if service.errors.any?
|
2
2
|
= bootstrap_alert(context: :danger, class: 'error-explanation') do
|
3
|
-
|
3
|
+
- message_default = t('errors.template.header', count: service.errors.count, model: service.class.model_name.human)
|
4
|
+
.error-heading= t('errors.template.services.header', count: service.errors.count, model: service.class.model_name.human, default: message_default)
|
4
5
|
%ul
|
5
6
|
- service.errors.full_messages.each do |msg|
|
6
7
|
%li= msg
|
data/config/locales/de.yml
CHANGED
@@ -10,6 +10,7 @@ de:
|
|
10
10
|
delete: Löschen
|
11
11
|
edit: Bearbeiten
|
12
12
|
show: Anzeigen
|
13
|
+
download: Download
|
13
14
|
table:
|
14
15
|
body_cells:
|
15
16
|
boolean:
|
@@ -17,7 +18,14 @@ de:
|
|
17
18
|
'false': Nein
|
18
19
|
header_cells:
|
19
20
|
batch_actions:
|
21
|
+
title: Stapelverarbeitung
|
20
22
|
destroy: Löschen
|
23
|
+
errors:
|
24
|
+
template:
|
25
|
+
services:
|
26
|
+
header:
|
27
|
+
one: "Konnte %{model} nicht ausführen: Ein Fehler"
|
28
|
+
other: "Konnte %{model} nicht ausführen: %{count} Fehler"
|
21
29
|
flash:
|
22
30
|
actions:
|
23
31
|
create:
|
@@ -76,3 +84,12 @@ de:
|
|
76
84
|
pagination:
|
77
85
|
last: '▶'
|
78
86
|
next: '◀'
|
87
|
+
search_form_builder:
|
88
|
+
predicates:
|
89
|
+
cont: "%{attribute_name} enthält"
|
90
|
+
eq: "%{attribute_name} ist"
|
91
|
+
boolean_label: "%{attribute_name}?"
|
92
|
+
submit: Suchen
|
93
|
+
reset: Zurücksetzen
|
94
|
+
'yes': Ja
|
95
|
+
'no': Nein
|
@@ -4,4 +4,28 @@ Rails::AddOns.configure do |config|
|
|
4
4
|
# Default: config.table_default_timestamp_format = nil
|
5
5
|
#
|
6
6
|
config.table_default_timestamp_format = nil
|
7
|
+
|
8
|
+
# Sets the parent controller for Api::ServiceController::Base
|
9
|
+
#
|
10
|
+
# default: config.api_service_controller_base_class_name = '::ApiController'
|
11
|
+
#
|
12
|
+
config.api_service_controller_base_class_name = '::ApiController'
|
13
|
+
|
14
|
+
# Sets the parent controller for Api::ResourcesController::Base
|
15
|
+
#
|
16
|
+
# default: config.api_resources_controller_base_class_name = '::ApiController'
|
17
|
+
#
|
18
|
+
config.api_resources_controller_base_class_name = '::ApiController'
|
19
|
+
|
20
|
+
# Sets the parent controller for ServiceController::Base
|
21
|
+
#
|
22
|
+
# default: config.service_controller_base_class_name = '::FrontendController'
|
23
|
+
#
|
24
|
+
config.service_controller_base_class_name = '::FrontendController'
|
25
|
+
|
26
|
+
# Sets the parent controller for ResourcesController::Base
|
27
|
+
#
|
28
|
+
# default: config.resources_controller_base_class_name = '::FrontendController'
|
29
|
+
#
|
30
|
+
config.resources_controller_base_class_name = '::FrontendController'
|
7
31
|
end
|
@@ -5,7 +5,11 @@ module Rails
|
|
5
5
|
yield self
|
6
6
|
end
|
7
7
|
|
8
|
-
mattr_accessor(:table_default_timestamp_format)
|
8
|
+
mattr_accessor(:table_default_timestamp_format) { :short }
|
9
|
+
mattr_accessor(:api_service_controller_base_class_name) { '::ApiController' }
|
10
|
+
mattr_accessor(:api_resources_controller_base_class_name) { '::ApiController' }
|
11
|
+
mattr_accessor(:service_controller_base_class_name) { '::FrontendController' }
|
12
|
+
mattr_accessor(:resources_controller_base_class_name) { '::FrontendController' }
|
9
13
|
end
|
10
14
|
end
|
11
15
|
end
|
@@ -87,7 +87,8 @@ module Rails
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def matches?(base_path)
|
90
|
-
@base_path =
|
90
|
+
@base_path = @spec.class.name.split('::')[0..2].join('::').constantize.description
|
91
|
+
# @base_path = base_path
|
91
92
|
@new_path = "#{@base_path}/new"
|
92
93
|
|
93
94
|
@spec.visit(@new_path)
|
@@ -111,11 +112,16 @@ module Rails
|
|
111
112
|
end
|
112
113
|
|
113
114
|
def has_correct_status_code
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
115
|
+
begin
|
116
|
+
if @spec.status_code == 200
|
117
|
+
true
|
118
|
+
else
|
119
|
+
@error = "Wrong status code [#{@spec.status_code}] instead of [200]"
|
120
|
+
false
|
121
|
+
end
|
122
|
+
rescue Capybara::NotSupportedByDriverError => e
|
123
|
+
puts "[Warning] Skipping status code check as it is not supported by your driver [#{@spec.driver.instance_variable_get(:@name)}]."
|
124
|
+
return true
|
119
125
|
end
|
120
126
|
end
|
121
127
|
|
@@ -47,7 +47,8 @@ module Rails
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def matches?(base_path)
|
50
|
-
@base_path =
|
50
|
+
@base_path = @spec.class.name.split('::')[0..2].join('::').constantize.description
|
51
|
+
# @base_path = base_path
|
51
52
|
@expected_path = @base_path
|
52
53
|
@show_path = "#{@base_path}/#{id}"
|
53
54
|
|
@@ -65,11 +66,16 @@ module Rails
|
|
65
66
|
end
|
66
67
|
|
67
68
|
def has_correct_status_code
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
begin
|
70
|
+
if @spec.status_code == 200
|
71
|
+
true
|
72
|
+
else
|
73
|
+
@error = "Wrong status code [#{@spec.status_code}] instead of [200]"
|
74
|
+
false
|
75
|
+
end
|
76
|
+
rescue Capybara::NotSupportedByDriverError => e
|
77
|
+
puts "[Warning] Skipping status code check as it is not supported by your driver [#{@spec.driver.instance_variable_get(:@name)}]."
|
78
|
+
return true
|
73
79
|
end
|
74
80
|
end
|
75
81
|
|
@@ -22,17 +22,24 @@ module Rails
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def matches?(base_path)
|
25
|
-
@base_path =
|
25
|
+
@base_path = @spec.class.name.split('::')[0..2].join('::').constantize.description
|
26
|
+
# @base_path = base_path
|
27
|
+
|
26
28
|
@spec.visit(@base_path)
|
27
29
|
has_correct_status_code && has_correct_current_path
|
28
30
|
end
|
29
31
|
|
30
32
|
def has_correct_status_code
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
begin
|
34
|
+
if @spec.status_code == 200
|
35
|
+
true
|
36
|
+
else
|
37
|
+
@error = "Wrong status code [#{@spec.status_code}] instead of [200]"
|
38
|
+
false
|
39
|
+
end
|
40
|
+
rescue Capybara::NotSupportedByDriverError => e
|
41
|
+
puts "[Warning] Skipping status code check as it is not supported by your driver [#{@spec.driver.instance_variable_get(:@name)}]."
|
42
|
+
return true
|
36
43
|
end
|
37
44
|
end
|
38
45
|
|
@@ -32,20 +32,25 @@ module Rails
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def matches?(base_path)
|
35
|
-
@base_path
|
35
|
+
@base_path = @spec.class.name.split('::')[0..2].join('::').constantize.description
|
36
|
+
# @base_path = base_path
|
36
37
|
@expected_path = "#{@base_path}/#{id}"
|
37
38
|
|
38
39
|
@spec.visit(@expected_path)
|
39
|
-
|
40
40
|
has_correct_status_code && has_correct_current_path
|
41
41
|
end
|
42
42
|
|
43
43
|
def has_correct_status_code
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
begin
|
45
|
+
if @spec.status_code == 200
|
46
|
+
true
|
47
|
+
else
|
48
|
+
@error = "Wrong status code [#{@spec.status_code}] instead of [200]"
|
49
|
+
false
|
50
|
+
end
|
51
|
+
rescue Capybara::NotSupportedByDriverError => e
|
52
|
+
puts "[Warning] Skipping status code check as it is not supported by your driver [#{@spec.driver.instance_variable_get(:@name)}]."
|
53
|
+
return true
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
@@ -59,17 +64,17 @@ module Rails
|
|
59
64
|
end
|
60
65
|
|
61
66
|
def failure_message
|
62
|
-
"Should expose show action on #{@
|
67
|
+
"Should expose show action on #{@expected_path}. Error: #{@error}"
|
63
68
|
end
|
64
69
|
|
65
70
|
def failure_message_when_negated
|
66
|
-
"Should not expose show action on #{@
|
71
|
+
"Should not expose show action on #{@expected_path}. Error: #{@error}"
|
67
72
|
end
|
68
73
|
|
69
74
|
alias negative_failure_message failure_message_when_negated
|
70
75
|
|
71
76
|
def description
|
72
|
-
"expose show action on #{@
|
77
|
+
"expose show action on #{@expected_path}"
|
73
78
|
end
|
74
79
|
end
|
75
80
|
end
|
@@ -80,7 +80,8 @@ module Rails
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def matches?(base_path)
|
83
|
-
@base_path =
|
83
|
+
@base_path = @spec.class.name.split('::')[0..2].join('::').constantize.description
|
84
|
+
# @base_path = base_path
|
84
85
|
@show_path = "#{@base_path}/#{id}"
|
85
86
|
@edit_path = "#{@base_path}/#{id}/edit"
|
86
87
|
|
@@ -101,11 +102,16 @@ module Rails
|
|
101
102
|
end
|
102
103
|
|
103
104
|
def has_correct_status_code
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
105
|
+
begin
|
106
|
+
if @spec.status_code == 200
|
107
|
+
true
|
108
|
+
else
|
109
|
+
@error = "Wrong status code [#{@spec.status_code}] instead of [200]"
|
110
|
+
false
|
111
|
+
end
|
112
|
+
rescue Capybara::NotSupportedByDriverError => e
|
113
|
+
puts "[Warning] Skipping status code check as it is not supported by your driver [#{@spec.driver.instance_variable_get(:@name)}]."
|
114
|
+
return true
|
109
115
|
end
|
110
116
|
end
|
111
117
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-add_ons
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roberto Vasquez Angel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry-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'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: haml-rails
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -177,13 +191,14 @@ files:
|
|
177
191
|
- app/assets/config/rails_add_ons_manifest.js
|
178
192
|
- app/assets/javascripts/rails/add_ons/application.js
|
179
193
|
- app/assets/javascripts/rails/add_ons/application/acts-as-list.js.coffee
|
194
|
+
- app/assets/javascripts/rails/add_ons/application/autosubmit.js.coffee
|
180
195
|
- app/assets/javascripts/rails/add_ons/application/widgets.js.coffee
|
181
196
|
- app/assets/javascripts/rails_add_ons.js
|
182
|
-
- app/assets/stylesheets/rails/add_ons/application.
|
183
|
-
- app/assets/stylesheets/rails/add_ons/application/bootstrap_overrides.
|
184
|
-
- app/assets/stylesheets/rails/add_ons/application/table_monospaced.
|
185
|
-
- app/assets/stylesheets/rails/add_ons/application/widgets.
|
186
|
-
- app/assets/stylesheets/rails/add_ons/bootstrap_v3_flex_extension.
|
197
|
+
- app/assets/stylesheets/rails/add_ons/application.css
|
198
|
+
- app/assets/stylesheets/rails/add_ons/application/bootstrap_overrides.css
|
199
|
+
- app/assets/stylesheets/rails/add_ons/application/table_monospaced.css
|
200
|
+
- app/assets/stylesheets/rails/add_ons/application/widgets.css
|
201
|
+
- app/assets/stylesheets/rails/add_ons/bootstrap_v3_flex_extension.css
|
187
202
|
- app/assets/stylesheets/rails/add_ons/font_awesome.css
|
188
203
|
- app/assets/stylesheets/rails_add_ons.css
|
189
204
|
- app/caches/api/cache.rb
|
@@ -197,6 +212,7 @@ files:
|
|
197
212
|
- app/concerns/component/collection_table/batch_actions_concern.rb
|
198
213
|
- app/concerns/component/collection_table/boolean_concern.rb
|
199
214
|
- app/concerns/component/resource_table/boolean_concern.rb
|
215
|
+
- app/concerns/controller/autosubmit_concern.rb
|
200
216
|
- app/concerns/controller/query_conditions.rb
|
201
217
|
- app/concerns/resources_controller/acts_as_list_concern.rb
|
202
218
|
- app/concerns/resources_controller/acts_as_published_concern.rb
|
@@ -210,6 +226,7 @@ files:
|
|
210
226
|
- app/concerns/resources_controller/resources.rb
|
211
227
|
- app/concerns/resources_controller/rest_actions.rb
|
212
228
|
- app/concerns/resources_controller/rest_resource_urls.rb
|
229
|
+
- app/concerns/resources_controller/search_form_concern.rb
|
213
230
|
- app/concerns/resources_controller/sorting.rb
|
214
231
|
- app/concerns/resources_controller/will_paginate.rb
|
215
232
|
- app/concerns/service_controller/location_history.rb
|
@@ -223,6 +240,8 @@ files:
|
|
223
240
|
- app/controllers/resources_controller/base.rb
|
224
241
|
- app/controllers/service_controller/base.rb
|
225
242
|
- app/extensions/object_extensions.rb
|
243
|
+
- app/helpers/rails/add_ons/autosubmit_helper.rb
|
244
|
+
- app/helpers/rails/add_ons/search_form_helper.rb
|
226
245
|
- app/helpers/rails/add_ons/table_helper.rb
|
227
246
|
- app/helpers/rails/add_ons/widget_helper.rb
|
228
247
|
- app/parsers/api/resources_controller/condition_parser.rb
|
@@ -309,9 +328,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
309
328
|
version: '0'
|
310
329
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
311
330
|
requirements:
|
312
|
-
- - "
|
331
|
+
- - ">"
|
313
332
|
- !ruby/object:Gem::Version
|
314
|
-
version:
|
333
|
+
version: 1.3.1
|
315
334
|
requirements: []
|
316
335
|
rubyforge_project:
|
317
336
|
rubygems_version: 2.6.11
|