rails-add_ons 2.2.1 → 3.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|