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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/rails/add_ons/application/autosubmit.js.coffee +4 -0
  3. data/app/assets/stylesheets/rails/add_ons/application/{bootstrap_overrides.scss → bootstrap_overrides.css} +0 -0
  4. data/app/assets/stylesheets/rails/add_ons/application/{table_monospaced.scss → table_monospaced.css} +0 -0
  5. data/app/assets/stylesheets/rails/add_ons/application/{widgets.scss → widgets.css} +0 -0
  6. data/app/assets/stylesheets/rails/add_ons/application.css +3 -0
  7. data/app/assets/stylesheets/rails/add_ons/{bootstrap_v3_flex_extension.scss → bootstrap_v3_flex_extension.css} +0 -0
  8. data/app/components/component/collection_table.rb +4 -0
  9. data/app/concerns/component/collection_table/batch_actions_concern.rb +4 -0
  10. data/app/concerns/controller/autosubmit_concern.rb +48 -0
  11. data/app/concerns/controller/query_conditions.rb +18 -1
  12. data/app/concerns/resources_controller/acts_as_list_concern.rb +7 -1
  13. data/app/concerns/resources_controller/batch_actions_concern.rb +9 -2
  14. data/app/concerns/resources_controller/location_history.rb +1 -0
  15. data/app/concerns/resources_controller/rest_actions.rb +4 -3
  16. data/app/concerns/resources_controller/search_form_concern.rb +9 -0
  17. data/app/concerns/resources_controller/will_paginate.rb +16 -2
  18. data/app/concerns/service_controller/rest_actions.rb +1 -1
  19. data/app/controllers/api/resources_controller/base.rb +1 -1
  20. data/app/controllers/api/service_controller/base.rb +1 -1
  21. data/app/controllers/resources_controller/base.rb +1 -1
  22. data/app/controllers/service_controller/base.rb +1 -1
  23. data/app/helpers/rails/add_ons/autosubmit_helper.rb +11 -0
  24. data/app/helpers/rails/add_ons/search_form_helper.rb +103 -0
  25. data/app/parsers/api/resources_controller/condition_parser.rb +62 -16
  26. data/app/views/component/table/header_cells/_batch_actions.haml +1 -1
  27. data/app/views/service_controller/base/_form_errors.haml +2 -1
  28. data/config/locales/de.yml +17 -0
  29. data/lib/generators/rails/add_ons/templates/initializer.rb +24 -0
  30. data/lib/rails/add_ons/configuration.rb +5 -1
  31. data/lib/rails/add_ons/shoulda/matchers/implement_create_action_matcher.rb +12 -6
  32. data/lib/rails/add_ons/shoulda/matchers/implement_delete_action_matcher.rb +12 -6
  33. data/lib/rails/add_ons/shoulda/matchers/implement_index_action_matcher.rb +13 -6
  34. data/lib/rails/add_ons/shoulda/matchers/implement_show_action_matcher.rb +15 -10
  35. data/lib/rails/add_ons/shoulda/matchers/implement_update_action_matcher.rb +12 -6
  36. data/lib/rails/add_ons/version.rb +1 -1
  37. metadata +28 -9
  38. 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: 1c7c4f39bddae1458684c318b7c5eb56192a5807
4
- data.tar.gz: 837bb68a45e06765a53361094424189022aac308
3
+ metadata.gz: cbbb783440b059a3b92ea129bd2f842870974373
4
+ data.tar.gz: caee54825a95a1bb70770ca526d967a8178c09c2
5
5
  SHA512:
6
- metadata.gz: 0b3ea72bef606239b4f36ef3a3f968cade7414a163fed52b017065206141ccef0bb73a00db0cc66dbd9cc37259425e97834e50702e34f67e40b15c353226c5e6
7
- data.tar.gz: 1e719c48c0dfece1b0a28c9cbfe0b2084b70527a551a3c16f20b0b58aa10b47e4ab307c80447fc38b04ca3cb5c129c772cf0678b7ee75c0eff854f2088432b1d
6
+ metadata.gz: 0cd22f3de8861299824bb3c9fbf377f8b9a920c6a71db291774f6a36bb5a514eaf72a1ec8eb112a6f33e77e40ac7177545edf7f5b7d16e3d72f817925eaec15f
7
+ data.tar.gz: 3ec98bb46404d2dc7d356ec2b7cec645cdbb87f481cf020a9c5c968ebc1f5fc1d6c8c72ef68e9312b5d74c3665fc0e6a0e9f7a357685c97d0c8657c2e5ff5aee
@@ -0,0 +1,4 @@
1
+ $ ->
2
+ $('[data-autosubmit="true"]').each ->
3
+ $(this).closest("form").append('<div class="loading">Loading&#8230;</div>')
4
+ $(this).closest("form").submit()
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require_tree ./application/
3
+ */
@@ -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.each do |field, condition|
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 collection_path, notice: I18n.t("acts_as_list.flash.actions.reposition.inserted_#{position}", target_resource: target_resource_label, inserted_resource: inserted_resource_label)
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, noticse: t('.success')
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
@@ -17,6 +17,7 @@ module ResourcesController
17
17
  def store_location
18
18
  return if request.referer.nil?
19
19
  truncate_location_history(9)
20
+ puts "[LocationHistoryConcern] Storing last location [#{request.referer}]"
20
21
  location_history[Time.zone.now] = request.referer
21
22
  end
22
23
 
@@ -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)
@@ -0,0 +1,9 @@
1
+ module ResourcesController
2
+ module SearchFormConcern
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ helper Rails::AddOns::SearchFormHelper
7
+ end
8
+ end
9
+ end
@@ -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
- @collection = load_collection_scope.paginate(page: params[:page])
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
@@ -1,6 +1,6 @@
1
1
  module Api
2
2
  module ResourcesController
3
- class Base < ::ApiController
3
+ class Base < Rails::AddOns::Configuration.api_resources_controller_base_class_name.constantize
4
4
  module RestActions
5
5
  extend ActiveSupport::Concern
6
6
 
@@ -1,6 +1,6 @@
1
1
  module Api
2
2
  module ServiceController
3
- class Base < ::ApiController
3
+ class Base < Rails::AddOns::Configuration.api_service_controller_base_class_name.constantize
4
4
  module RestActions
5
5
  extend ActiveSupport::Concern
6
6
 
@@ -1,5 +1,5 @@
1
1
  module ResourcesController
2
- class Base < ::FrontendController
2
+ class Base < Rails::AddOns::Configuration.resources_controller_base_class_name.constantize
3
3
  layout 'rails/add_ons/application'
4
4
 
5
5
  include RestActions
@@ -1,5 +1,5 @@
1
1
  module ServiceController
2
- class Base < ::FrontendController
2
+ class Base < Rails::AddOns::Configuration.service_controller_base_class_name.constantize
3
3
  layout 'rails/add_ons/application'
4
4
 
5
5
  include ServiceController::Service
@@ -0,0 +1,11 @@
1
+ module Rails
2
+ module AddOns
3
+ module AutosubmitHelper
4
+ def autosubmit
5
+ if autosubmit_now?
6
+ content_tag(:div, nil, data: { autosubmit: true} ).html_safe
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -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 = extract_column_and_operator(parent_key)
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
- if column_is_boolean?(column)
30
- ["#{column} = ?", to_boolean(condition)]
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
- return $~[1], $~[2]
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 column_name =~ /(.*)\.(.*)/
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
- ActiveRecord::ConnectionAdapters::Column.value_to_boolean(string)
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('.batch_actions')
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
- .error-heading= t('errors.template.header', count: service.errors.count, model: service.class.model_name.human)
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
@@ -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: '&#9654;'
78
86
  next: '&#9664;'
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) { :short }
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 = 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
- if @spec.status_code == 200
115
- true
116
- else
117
- @error = "Wrong status code [#{@spec.status_code}] instead of [200]"
118
- false
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 = 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
- if @spec.status_code == 200
69
- true
70
- else
71
- @error = "Wrong status code [#{@spec.status_code}] instead of [200]"
72
- false
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 = 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
- if @spec.status_code == 200
32
- true
33
- else
34
- @error = "Wrong status code [#{@spec.status_code}] instead of [200]"
35
- false
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 = 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
- if @spec.status_code == 200
45
- true
46
- else
47
- @error = "Wrong status code [#{@spec.status_code}] instead of [200]"
48
- false
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 #{@base_path}. Error: #{@error}"
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 #{@base_path}. Error: #{@error}"
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 #{@base_path}"
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 = 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
- if @spec.status_code == 200
105
- true
106
- else
107
- @error = "Wrong status code [#{@spec.status_code}] instead of [200]"
108
- false
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
 
@@ -1,5 +1,5 @@
1
1
  module Rails
2
2
  module AddOns
3
- VERSION = '2.2.1'.freeze
3
+ VERSION = '3.0.0.pre1'.freeze
4
4
  end
5
5
  end
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: 2.2.1
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: 2018-03-25 00:00:00.000000000 Z
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.scss
183
- - app/assets/stylesheets/rails/add_ons/application/bootstrap_overrides.scss
184
- - app/assets/stylesheets/rails/add_ons/application/table_monospaced.scss
185
- - app/assets/stylesheets/rails/add_ons/application/widgets.scss
186
- - app/assets/stylesheets/rails/add_ons/bootstrap_v3_flex_extension.scss
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: '0'
333
+ version: 1.3.1
315
334
  requirements: []
316
335
  rubyforge_project:
317
336
  rubygems_version: 2.6.11
@@ -1,3 +0,0 @@
1
- @import "application/bootstrap_overrides";
2
- @import "application/table_monospaced";
3
- @import "application/widgets";