adminos 1.0.0.pre.rc.2 → 1.0.0.pre.rc.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -4
  3. data/README.md +26 -0
  4. data/adminos.gemspec +4 -4
  5. data/app/inputs/cropp_input.rb +15 -3
  6. data/app/inputs/filter_inputs/boolean_input.rb +18 -0
  7. data/app/inputs/filter_inputs/date_range_input.rb +36 -0
  8. data/app/inputs/filter_inputs/numeric_input.rb +40 -0
  9. data/app/inputs/filter_inputs/string_input.rb +40 -0
  10. data/lib/adminos/configuration.rb +9 -0
  11. data/lib/adminos/controllers/filters.rb +20 -0
  12. data/lib/adminos/controllers/resource.rb +34 -14
  13. data/lib/adminos/extensions/simple_form.rb +12 -0
  14. data/lib/adminos/features/search/elastic.rb +46 -0
  15. data/lib/adminos/features/search/pg_search.rb +49 -0
  16. data/lib/adminos/filters/forms.rb +55 -0
  17. data/lib/adminos/form_builder.rb +11 -0
  18. data/lib/adminos/helpers/models/searchable.rb +9 -0
  19. data/lib/adminos/helpers/view.rb +35 -0
  20. data/lib/adminos.rb +23 -3
  21. data/lib/generators/adminos/adminos_generator.rb +10 -7
  22. data/lib/generators/adminos/feedback_generator.rb +39 -0
  23. data/lib/generators/adminos/i18n_generator.rb +16 -4
  24. data/lib/generators/adminos/install_generator.rb +22 -0
  25. data/lib/generators/adminos/profile_generator.rb +34 -0
  26. data/lib/generators/adminos/search_generator.rb +38 -0
  27. data/lib/generators/adminos/two_factor_auth_generator.rb +81 -0
  28. data/lib/generators/templates/adminos/fields.slim +1 -1
  29. data/lib/generators/templates/adminos/locales/locale_fields.slim +7 -4
  30. data/lib/generators/templates/adminos/locales/model.rb.erb +2 -3
  31. data/lib/generators/templates/ci/.gitlab-ci.yml +1 -1
  32. data/lib/generators/templates/feedback/auto/app/controllers/admin/feedbacks_controller.rb +17 -0
  33. data/lib/generators/templates/feedback/auto/app/controllers/feedbacks_controller.rb +11 -0
  34. data/lib/generators/templates/feedback/auto/app/models/feedback.rb +6 -0
  35. data/lib/generators/templates/feedback/auto/app/views/admin/feedbacks/_fields.slim +5 -0
  36. data/lib/generators/templates/feedback/auto/app/views/admin/feedbacks/index.slim +28 -0
  37. data/lib/generators/templates/feedback/feedbacks_migration.rb +13 -0
  38. data/lib/generators/templates/field/locales/locale_fields.slim +1 -1
  39. data/lib/generators/templates/field/locales/model.rb.erb +2 -3
  40. data/lib/generators/templates/i18n/Gemfile +6 -1
  41. data/lib/generators/templates/i18n/auto/app/validators/locale_validator.rb +5 -1
  42. data/lib/generators/templates/i18n/auto/app/views/admin/base/_pills.slim +1 -5
  43. data/lib/generators/templates/i18n/auto/app/views/admin/pages/_locale_fields.slim +5 -5
  44. data/lib/generators/templates/i18n/auto/config/initializers/mobility.rb +92 -0
  45. data/lib/generators/templates/i18n/devise/devise.ru.yml +15 -3
  46. data/lib/generators/templates/i18n/devise/views/mailer/confirmation_instructions.slim +3 -4
  47. data/lib/generators/templates/i18n/devise/views/mailer/reset_password_instructions.slim +5 -5
  48. data/lib/generators/templates/i18n/devise/views/mailer/unlock_instructions.slim +4 -4
  49. data/lib/generators/templates/i18n/page.rb +2 -2
  50. data/lib/generators/templates/install/Gemfile +4 -6
  51. data/lib/generators/templates/install/README.md +22 -0
  52. data/lib/generators/templates/install/admin_panel/versions/views/admin_versions/index.slim +1 -1
  53. data/lib/generators/templates/install/admin_panel/versions/views/admin_versions/show.slim +3 -3
  54. data/lib/generators/templates/install/auto/Capfile +12 -2
  55. data/lib/generators/templates/install/auto/app/controllers/admin/settings_controller.rb +1 -1
  56. data/lib/generators/templates/install/auto/app/helpers/versions_helper.rb +3 -3
  57. data/lib/generators/templates/install/auto/app/inputs/carrierwave_input.rb +2 -2
  58. data/lib/generators/templates/install/auto/app/inputs/checkbox_input.rb +1 -1
  59. data/lib/generators/templates/install/auto/app/services/export_xlsx.rb +6 -6
  60. data/lib/generators/templates/install/auto/app/views/admin/base/_form.slim +3 -3
  61. data/lib/generators/templates/install/auto/app/views/admin/helps/index.slim +9 -9
  62. data/lib/generators/templates/install/auto/app/views/admin/settings/edit.slim +2 -2
  63. data/lib/generators/templates/install/auto/app/views/shared/admin/_back_button.slim +1 -1
  64. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_collection_header.slim +2 -0
  65. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_object_link_new.slim +1 -1
  66. data/lib/generators/templates/install/auto/config/deploy/staging.rb +15 -10
  67. data/lib/generators/templates/install/auto/config/deploy/{shared → templates}/database.yml.erb +1 -1
  68. data/lib/generators/templates/install/auto/config/deploy/templates/nginx_conf.erb +96 -0
  69. data/lib/generators/templates/install/auto/config/deploy/templates/puma.rb.erb +52 -0
  70. data/lib/generators/templates/install/auto/config/environments/staging.rb +1 -1
  71. data/lib/generators/templates/install/auto/config/initializers/adminos.rb +3 -0
  72. data/lib/generators/templates/install/auto/config/locales/adminos.en.yml +30 -0
  73. data/lib/generators/templates/install/auto/config/locales/adminos.ru.yml +49 -2
  74. data/lib/generators/templates/install/auto/config/schedule.rb +0 -0
  75. data/lib/generators/templates/install/auto/config/systemd/puma.service.erb +19 -0
  76. data/lib/generators/templates/install/auto/config/systemd/sidekiq.service.erb +21 -0
  77. data/lib/generators/templates/install/auto/lib/capistrano/{template.rb → smart_templates.rb} +17 -3
  78. data/lib/generators/templates/install/auto/lib/capistrano/tasks/setup_config.cap +27 -20
  79. data/lib/generators/templates/install/deploy.rb.erb +13 -12
  80. data/lib/generators/templates/install/prepare_settings.rb +1 -1
  81. data/lib/generators/templates/profile/auto/app/controllers/admin/profiles_controller.rb +26 -0
  82. data/lib/generators/templates/profile/auto/app/views/admin/profiles/edit.slim +17 -0
  83. data/lib/generators/templates/two_facto_auth/Gemfile +1 -0
  84. data/lib/generators/templates/two_facto_auth/auto/app/controllers/concerns/authenticates_with_two_factor.rb +36 -0
  85. data/lib/generators/templates/two_facto_auth/auto/app/controllers/users/sessions_controller.rb +5 -0
  86. data/lib/generators/templates/two_facto_auth/auto/app/views/admin/profiles/_2fa.slim +24 -0
  87. data/lib/generators/templates/two_facto_auth/auto/app/views/devise/sessions/two_factor.slim +15 -0
  88. data/spec/lib/generators/adminos/feedback_generator_rspec.rb +50 -0
  89. data/spec/lib/generators/adminos/install_generator_rspec.rb +6 -7
  90. data/spec/lib/generators/adminos/profile_generator_rspec.rb +33 -0
  91. data/spec/lib/generators/adminos/search_generator.rb +20 -0
  92. data/spec/lib/generators/adminos/two_factor_auth_generator_rspec.rb +61 -0
  93. data/spec/spec_helper.rb +4 -0
  94. data/spec/support/shared/generator.rb +1 -1
  95. metadata +59 -26
  96. data/bin/rspec +0 -29
  97. data/lib/adminos/extensions/globalize_actiontext.rb +0 -28
  98. data/lib/adminos/extensions/globalize_fields.rb +0 -19
  99. data/lib/generators/templates/adminos/locales/migration.rb.erb +0 -18
  100. data/lib/generators/templates/field/locales/migration.rb.erb +0 -13
  101. data/lib/generators/templates/i18n/add_translation_table_to_page.rb +0 -15
  102. data/lib/generators/templates/i18n/auto/config/initializers/globalize_fields.rb +0 -1
  103. data/lib/generators/templates/install/auto/config/deploy/shared/nginx.conf.erb +0 -28
  104. data/lib/generators/templates/install/auto/config/deploy/shared/unicorn.rb.erb +0 -35
  105. data/lib/generators/templates/install/auto/lib/capistrano/substitute_strings.rb +0 -12
  106. data/package-lock.json +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1dd7956b8e247ace0302f2da00df9bd1a437de8b0ed52bc1e5bb575fe4889fcc
4
- data.tar.gz: 2980ad30232cc36f622c1059c6c77e0273500a6ba53cd9513e4c66e10aedd012
3
+ metadata.gz: 5db7ce49022e65e508406169c6b1d4f04ee53476e86d5a3051ff5a9038fdcf0e
4
+ data.tar.gz: 8f22b81628986dc312eaa231abd161ba5a4d330efc6da068f222f0d8f2f32fb0
5
5
  SHA512:
6
- metadata.gz: 7271cb01c26fc3fc4471fffa46ee1250934f85872b2438eb7d590d13334585ca78a1347968254913e0a00383e9ee0a90041b46e33b046149f326c75b509750cc
7
- data.tar.gz: 50b733a689694add1c82c11b26eadb3fc8abf3a7212fe1bca1dc22ffa8395d9335b7c4feb073a5c380748dd4db6782113c9d1091d1383b4bf2ca3a23c6fc5ec2
6
+ metadata.gz: 60c4bb29efed943423d50c0c70fc0277d7dec13204910325133b2ba06169fb1cc64635e8342fef9c027eb97fc3b6c9ed19dbb0e7704ea29afddccbed0a2eb700
7
+ data.tar.gz: 1f8957927b86caa2a987c6e2a885ecb814bb9c00a30e88d488af88d6a54d1c9d58d7e9e01a6a61915b4bf0de9a00c4979bfc89fe3b845d42fcf32b237d75a937
data/Gemfile CHANGED
@@ -18,8 +18,7 @@ group :development do
18
18
  end
19
19
 
20
20
  gem 'guard-minitest', '~> 2.4'
21
- gem 'globalize'
22
21
  gem 'friendly_id'
23
- gem 'activerecord-nulldb-adapter', git: 'git://github.com/nulldb/nulldb.git'
24
- gem 'sqlite3'
25
- gem 'database_cleaner'
22
+ gem 'activerecord-nulldb-adapter', git: 'https://github.com/nulldb/nulldb.git'
23
+ gem 'sqlite3', '~> 1.3.6'
24
+ gem 'database_cleaner'
data/README.md CHANGED
@@ -51,6 +51,32 @@ If no need in SEO fields, switch it off using `--no-seo`.
51
51
  $ rails g adminos Model --no-seo
52
52
 
53
53
  ## Features
54
+ ### Filters
55
+
56
+ To add filtering by any attributes you need to add the required filters in the controller. Below is an example.
57
+
58
+ ```ruby
59
+ class Admin::ProductsController < Admin::BaseController
60
+ add_filter :name
61
+ add_filter :price
62
+ add_filter :published
63
+
64
+ #some code
65
+ end
66
+ ```
67
+
68
+ ### Search
69
+
70
+ By default, search is enabled only on user models.
71
+
72
+ To add a search, run the following generator.
73
+
74
+ ```
75
+ rails generate adminos:search ModelName
76
+ ```
77
+
78
+ You can use search engines such as ElasticSearch or PgSearch. By default, PgSearch is used if you did not specify the --search = elastic flag when installing adminos.
79
+
54
80
  ### Cropped
55
81
  model
56
82
  ```ruby
data/adminos.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'adminos'
3
- gem.version = '1.0.0-rc.2'
3
+ gem.version = '1.0.0-rc.4'
4
4
  gem.authors = ['RavWar', 'milushov', 'abuhtoyarov', 'SiebenSieben']
5
5
  gem.email = ['studio@molinos.ru']
6
6
  gem.homepage = 'https://gitlab.molinos.ru/global/adminos'
@@ -15,20 +15,20 @@ Gem::Specification.new do |gem|
15
15
 
16
16
  gem.add_dependency 'path'
17
17
  gem.add_dependency 'jquery-fileupload-rails'
18
- gem.add_dependency 'railties', '~> 5.1'
18
+ gem.add_dependency 'railties', '>= 5.1'
19
19
  gem.add_dependency 'dotenv-rails'
20
20
  gem.add_dependency 'slim-rails'
21
21
  gem.add_dependency 'friendly_id'
22
22
  gem.add_dependency 'babosa'
23
23
  gem.add_dependency 'simple_form'
24
24
  gem.add_dependency 'kaminari'
25
- gem.add_dependency 'russian'
26
25
  gem.add_dependency 'devise'
27
26
  gem.add_dependency 'cancancan'
28
27
  gem.add_dependency 'cocoon'
29
28
  gem.add_dependency 'awesome_nested_set'
29
+ gem.add_dependency 'ransack'
30
30
 
31
- gem.add_development_dependency 'bundler', '~> 1.3'
31
+ gem.add_development_dependency 'bundler', '~> 2.2'
32
32
  gem.add_development_dependency 'm'
33
33
  gem.add_development_dependency 'rails'
34
34
  gem.add_development_dependency 'rake'
@@ -6,7 +6,7 @@ class CroppInput < SimpleForm::Inputs::Base
6
6
  out = []
7
7
  out << %{<div class="f-file">}
8
8
  out << %{ <label class="f-file__selection js-file">}
9
- out << %{ <span class="f-file__button">Выбрать</span>}
9
+ out << %{ <span class="f-file__button">#{I18n.t('labels.admin.choose')}</span>}
10
10
  out << @builder.file_field(attribute_name, input_html_options)
11
11
  out << @builder.hidden_field(@coord_attribute)
12
12
  out << %{ <span class="f-file__selected"></span>}
@@ -23,13 +23,25 @@ class CroppInput < SimpleForm::Inputs::Base
23
23
 
24
24
  aspect_ratio = input_html_options.delete(:aspect_ratio) || '16/9'
25
25
  aspect_ratio = aspect_ratio.split('/').map(&:to_f)
26
- aspect_ratio = aspect_ratio[0]/aspect_ratio[1]
26
+ aspect_ratio = aspect_ratio[0] / aspect_ratio[1]
27
27
 
28
28
  out << %{<div class="row"><div class="col-md-8"><div class="img-container">}
29
29
 
30
30
  out << template.image_tag(object.send(attribute_name), data: { aspect_ratio: aspect_ratio, preview: ".#{@version}_#{attribute_name}_preview", toggle: 'cropp', coord: @coord_attribute })
31
31
 
32
32
  out << %{</div></div><div class="col-md-4">}
33
+ out << %{<div class="cropper-dimensions">}
34
+ out << %{<div class="field">}
35
+ out << template.label_tag(:width, I18n.t('labels.admin.image.width'), class: 'control-label')
36
+ out << template.number_field_tag(:width, nil, class: 'form-control')
37
+ out << %{</div>}
38
+ out << %{<div class="field">}
39
+
40
+ out << template.label_tag(:height, I18n.t('labels.admin.image.height'), class: 'control-label')
41
+ out << template.number_field_tag(:height, nil, class: 'form-control')
42
+ out << %{</div>}
43
+
44
+ out << %{</div>}
33
45
  out << %{<div class="docs-preview clearfix">}
34
46
  out << %{<div class="img-preview preview-lg #{@version}_#{attribute_name}_preview"></div>}
35
47
  out << cropped
@@ -46,7 +58,7 @@ class CroppInput < SimpleForm::Inputs::Base
46
58
 
47
59
  out << template.image_tag(object.send("#{@version}_#{attribute_name}_cropped"))
48
60
 
49
- out << %{<figcaption class="figure-caption text-center">Cropped image</figcaption></figure></div>}
61
+ out << %{<figcaption class="figure-caption text-center">#{I18n.t('labels.admin.image.width.cropped')}</figcaption></figure></div>}
50
62
  out.join
51
63
  end
52
64
  end
@@ -0,0 +1,18 @@
1
+ module FilterInputs
2
+ class BooleanInput < SimpleForm::Inputs::CollectionSelectInput
3
+ def input(wrapper_options = nil)
4
+ label_method, value_method = detect_collection_methods
5
+
6
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
7
+
8
+ @builder.collection_select(
9
+ filter_attribute_name, collection, value_method, label_method,
10
+ input_options, merged_input_options
11
+ )
12
+ end
13
+
14
+ def filter_attribute_name
15
+ "#{attribute_name}_eq"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ module FilterInputs
2
+ class DateRangeInput < SimpleForm::Inputs::StringInput
3
+ def input(wrapper_options = nil)
4
+ @wrapper_options = wrapper_options
5
+ out = []
6
+
7
+ out << input_html
8
+ out.join.html_safe
9
+ end
10
+
11
+ def input_html
12
+ merged_input_options = merge_wrapper_options(input_html_options, @wrapper_options)
13
+ [
14
+ @builder.text_field(gt_input_name, merged_input_options.merge(placeholder: gt_input_placeholder, class: 'date-picker form-control')),
15
+ @builder.text_field(lt_input_name, merged_input_options.merge(placeholder: lt_input_placeholder, class: 'date-picker form-control'))
16
+ ].join("\n").html_safe
17
+ end
18
+
19
+ def gt_input_name
20
+ "#{attribute_name}_gteq"
21
+ end
22
+ alias :input_name :gt_input_name
23
+
24
+ def lt_input_name
25
+ "#{attribute_name}_lteq"
26
+ end
27
+
28
+ def gt_input_placeholder
29
+ 'От'
30
+ end
31
+
32
+ def lt_input_placeholder
33
+ 'До'
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,40 @@
1
+ module FilterInputs
2
+ class NumericInput < SimpleForm::Inputs::StringInput
3
+ def input(wrapper_options = nil)
4
+ @wrapper_options = wrapper_options
5
+ out = []
6
+ out << select_html
7
+ out << input_html
8
+ out.join.html_safe
9
+ end
10
+
11
+ def select_html
12
+ template.select_tag '', template.options_for_select(filter_options, current_filter), class: 'select_filter form-control'
13
+ end
14
+
15
+ def input_html
16
+ merged_input_options = merge_wrapper_options(input_html_options, @wrapper_options)
17
+ @builder.text_field current_filter, merged_input_options.merge(class: 'form-control')
18
+ end
19
+
20
+ def current_filter
21
+ @current_filter ||= begin
22
+ attributes = filters.map { |f| "#{attribute_name}_#{f}" }
23
+ attributes.detect { |m| object.public_send m } || attributes.first
24
+ end
25
+ end
26
+
27
+ def label_html
28
+ end
29
+
30
+ def filter_options
31
+ filters.map do |filter|
32
+ [filter, "#{attribute_name}_#{filter}"]
33
+ end
34
+ end
35
+
36
+ def filters
37
+ %w(eq gt lt)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ module FilterInputs
2
+ class StringInput < SimpleForm::Inputs::StringInput
3
+ def input(wrapper_options = nil)
4
+ @wrapper_options = wrapper_options
5
+ out = []
6
+ out << select_html
7
+ out << input_html
8
+ out.join.html_safe
9
+ end
10
+
11
+ def select_html
12
+ template.select_tag '', template.options_for_select(filter_options, current_filter), class: 'select_filter form-control'
13
+ end
14
+
15
+ def input_html
16
+ merged_input_options = merge_wrapper_options(input_html_options, @wrapper_options)
17
+ @builder.text_field current_filter, merged_input_options.merge(class: 'form-control')
18
+ end
19
+
20
+ def current_filter
21
+ @current_filter ||= begin
22
+ attributes = filters.map { |f| "#{attribute_name}_#{f}" }
23
+ attributes.detect { |m| object.public_send m } || attributes.first
24
+ end
25
+ end
26
+
27
+ def label_html
28
+ end
29
+
30
+ def filter_options
31
+ filters.map do |filter|
32
+ [filter, "#{attribute_name}_#{filter}"]
33
+ end
34
+ end
35
+
36
+ def filters
37
+ %w(cont eq start end)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ module Adminos
2
+ class Configuration
3
+ attr_accessor :search_engine
4
+
5
+ def initialize
6
+ @search_engine = Adminos::Search::PgSearch
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ module Adminos::Controllers::Filters
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ helper_method :filters
6
+ end
7
+
8
+ class_methods do
9
+ attr_reader :filters
10
+
11
+ def add_filter(attribute, *args)
12
+ options = args.extract_options!
13
+ (@filters ||= {})[attribute.to_sym] = options
14
+ end
15
+ end
16
+
17
+ def filters
18
+ self.class.filters
19
+ end
20
+ end
@@ -19,7 +19,7 @@ module Adminos::Controllers::Resource
19
19
  with_move_to = options.delete(:with_move_to)
20
20
  with_apply_sortable_order = options.delete(:with_apply_sortable_order)
21
21
 
22
- helper_method :resource, :collection, :resource_class, :resource_params
22
+ helper_method :resource, :collection, :resource_class, :resource_params, :filter
23
23
  helper_method(:parent_resource) if with_parent_resource
24
24
 
25
25
  define_method :create do
@@ -31,7 +31,7 @@ module Adminos::Controllers::Resource
31
31
  end
32
32
 
33
33
  define_method :update do
34
- resource.update_attributes(parameters)
34
+ resource.update(parameters)
35
35
  respond_with(resource, location: self.instance_eval(&location))
36
36
  end
37
37
 
@@ -80,11 +80,15 @@ module Adminos::Controllers::Resource
80
80
  if with_parent_resource
81
81
  parent_resource.send(self.resource_as_association)
82
82
  elsif filter_by_locale
83
- resource_class.with_translations(I18n.locale)
83
+ Mobility.with_locale(I18n.locale) do
84
+ resource_class
85
+ end
84
86
  else
85
87
  resource_class
86
88
  end
87
89
 
90
+ collection = collection.search_by(params[:query]) if params[:query].present?
91
+
88
92
  @collection =
89
93
  if collection_scope.is_a?(Array)
90
94
  collection_scope.inject(collection) do |collection, method|
@@ -93,12 +97,19 @@ module Adminos::Controllers::Resource
93
97
  else
94
98
  collection.send(collection_scope)
95
99
  end
100
+
101
+ @collection = @collection.ransack(params[:q]).result if params[:q].present?
102
+ @collection
96
103
  end
97
104
 
98
105
  define_method :build_resource do
99
106
  self.resource_class_scope.new(parameters)
100
107
  end
101
108
 
109
+ define_method :filter do
110
+ @collection.ransack(params[:q])
111
+ end
112
+
102
113
  define_method :parameters do
103
114
  if action_name == ('create') || action_name == ('update')
104
115
  strong_params
@@ -119,19 +130,28 @@ module Adminos::Controllers::Resource
119
130
  reflect_has_one = resource_class.reflect_on_all_associations(:has_one)
120
131
  rich_text_attributes = reflect_has_one.map(&:name).map { |name| name.to_s.gsub('rich_text_', '') }.compact
121
132
 
122
- _attribute_names = self.resource_class_scope.attribute_names + ids_attributes + rich_text_attributes
123
-
124
- if params[resource_params][:translations_attributes]
125
- _translated_attributes = resource_class.translated_attribute_names
126
- attrs = _attribute_names + _translated_attributes
127
- attrs.push(translations_attributes: _translated_attributes + [:id, :locale]) unless _translated_attributes.blank?
128
-
129
- result = params.require(resource_params).permit(attrs)
130
- else
131
- result = params.require(resource_params).permit(*_attribute_names)
133
+ attachment_names = reflect_has_one.
134
+ map { |reflection| reflection.name.to_s }.
135
+ select { |name| name.match?(/_attachment/) }.
136
+ map { |name| name.chomp('_attachment').to_sym }
137
+
138
+ attachments_names = resource_class.
139
+ reflect_on_all_associations(:has_many).
140
+ map { |reflection| reflection.name.to_s }.
141
+ select { |name| name.match?(/_attachments/) }.
142
+ map { |name| { name.chomp('_attachments').to_sym => [] } }
143
+
144
+ _attribute_names = self.resource_class_scope.attribute_names +
145
+ attachment_names + ids_attributes +
146
+ rich_text_attributes + attachments_names
147
+
148
+ if resource_class.respond_to?(:translated_attribute_names)
149
+ _attribute_names += resource_class.translated_attribute_names.map do |attr|
150
+ I18n.available_locales.map { |locale| "#{attr}_#{Mobility.normalize_locale(locale)}" }
151
+ end.flatten
132
152
  end
133
153
 
134
- result
154
+ params.require(resource_params).permit(*_attribute_names)
135
155
  end
136
156
 
137
157
  define_method :find_resource do
@@ -0,0 +1,12 @@
1
+ module Adminos
2
+ module SimpleFormExtraBase
3
+ # Find reflection name when available, otherwise use attribute
4
+ def reflection_or_attribute_name
5
+ @reflection_or_attribute_name ||= reflection ? reflection.name : attribute_name
6
+ @reflection_or_attribute_name.to_s.gsub(/_(#{I18n.available_locales.join('|')})/, '')
7
+ end
8
+ end
9
+ end
10
+
11
+
12
+ SimpleForm::Inputs::Base.prepend(Adminos::SimpleFormExtraBase)
@@ -0,0 +1,46 @@
1
+ module Adminos
2
+ module Search
3
+ module Elastic
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ searchkick **searchkick_options
8
+
9
+ def search_data
10
+ data = respond_to?(:to_hash) ? to_hash : serializable_hash
11
+ data.delete("id")
12
+ data.delete("_id")
13
+ data.delete("_type")
14
+ data.merge!(actiontext_attributes)
15
+
16
+ data
17
+ end
18
+
19
+ def actiontext_attributes
20
+ reflect_has_one = self.class.reflect_on_all_associations(:has_one)
21
+ rich_text_attributes = reflect_has_one.map(&:name).map { |name| name if name.to_s.include?('rich_text_') }.compact
22
+
23
+ rich_text_attributes.inject({}) do |memo, attr|
24
+ memo[attr] = public_send(attr).to_plain_text
25
+ memo
26
+ end
27
+ end
28
+ end
29
+
30
+ class_methods do
31
+ def search_by(q = nil, *args)
32
+ options = args.extract_options!
33
+ options.merge!(load: false)
34
+
35
+ result_ids = self.search(q, options).results.map(&:id)
36
+
37
+ where(id: result_ids)
38
+ end
39
+
40
+ def searchkick_options
41
+ {}
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,49 @@
1
+ module Adminos
2
+ module Search
3
+ module PgSearch
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ include ::PgSearch
8
+
9
+ pg_search_scope :search_by, against: :email, using: {
10
+ tsearch: { any_word: true, prefix: true }
11
+ }
12
+ end
13
+
14
+ class_methods do
15
+ def search_fields
16
+ base_search_fields + against
17
+ end
18
+
19
+ def associated_fields
20
+ data = associated_against
21
+ data.merge!(actiontext_attributes)
22
+ data
23
+ end
24
+
25
+ def associated_against
26
+ {}
27
+ end
28
+
29
+ def against
30
+ []
31
+ end
32
+
33
+ def actiontext_attributes
34
+ reflect_has_one = self.reflect_on_all_associations(:has_one)
35
+ rich_text_attributes = reflect_has_one.map(&:name).map { |name| name if name.to_s.include?('rich_text_') }.compact
36
+
37
+ rich_text_attributes.inject({}) do |memo, attr|
38
+ memo[attr] = [:body]
39
+ memo
40
+ end
41
+ end
42
+
43
+ def base_search_fields
44
+ self.columns.map { |c| c.name if [:string, :text].include?(c.type) }.compact
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,55 @@
1
+ module Adminos
2
+ module Filters
3
+ class FormBuilder < ::Adminos::FormBuilder
4
+ map_type :date_range, to: SimpleForm::Inputs::DateTimeInput
5
+ map_type :numeric, to: SimpleForm::Inputs::NumericInput
6
+
7
+ def filter(attribute_name, options = {})
8
+ if attribute_name.present? && options[:as] ||= input_type(attribute_name)
9
+ template.concat input(attribute_name, options)
10
+ end
11
+ end
12
+
13
+ def input_type(attribute_name)
14
+ column = find_attribute_column(attribute_name)
15
+ input_type = default_input_type(attribute_name, column, {})
16
+
17
+ case input_type
18
+ when :date, :datetime
19
+ :date_range
20
+ when :string, :text, :jsonb, :email
21
+ :string
22
+ when :integer, :float, :decimal
23
+ :numeric
24
+ when :boolean
25
+ :boolean
26
+ end
27
+ end
28
+
29
+ def klass
30
+ @object.object
31
+ end
32
+
33
+ def find_attribute_column(attribute_name)
34
+ if klass.respond_to?(:type_for_attribute) && klass.has_attribute?(attribute_name)
35
+ klass.type_for_attribute(attribute_name.to_s)
36
+ elsif klass.respond_to?(:column_for_attribute) && klass.has_attribute?(attribute_name)
37
+ klass.column_for_attribute(attribute_name)
38
+ end
39
+ end
40
+
41
+ def find_mapping(input_type)
42
+ if mapping = self.class.mappings[input_type]
43
+ mapping_override(mapping) || mapping
44
+ camelized = "#{input_type.to_s.camelize}Input"
45
+
46
+ attempt_mapping(camelized, FilterInputs) ||
47
+ attempt_mapping_with_custom_namespace(camelized) ||
48
+ attempt_mapping(camelized, Object) ||
49
+ attempt_mapping(camelized, self.class) ||
50
+ raise("No input found for #{input_type}")
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,11 @@
1
+ module Adminos
2
+ class FormBuilder < SimpleForm::FormBuilder
3
+ def input(attribute_name, options = {}, &block)
4
+ locale = options.delete(:locale)
5
+
6
+ attribute_name = [attribute_name, locale].compact.join('_')
7
+
8
+ super(attribute_name, options, &block)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Adminos::Searchable
2
+ extend ActiveSupport::Concern
3
+
4
+ class_methods do
5
+ def searchable(*args)
6
+ include Adminos.configuration.search_engine
7
+ end
8
+ end
9
+ end
@@ -1,4 +1,39 @@
1
1
  module Adminos::Helpers::View
2
+ def adminos_form_for(object, *args, &block)
3
+ options = args.extract_options!
4
+ simple_form_for(object, *(args << options.merge(builder: Adminos::FormBuilder)), &block)
5
+ end
6
+
7
+ # Helper method to render a filter form
8
+ def adminos_filters_form_for(filters, options = {})
9
+ return if filters.blank?
10
+
11
+ defaults = {
12
+ builder: Adminos::Filters::FormBuilder,
13
+ method: :get,
14
+ url: polymorphic_path([:admin, resource_class]),
15
+ html: { class: 'form-inline filter-form' }
16
+ }
17
+
18
+ form_for resource_class.ransack(params[:q]), defaults do |f|
19
+
20
+ filters.each do |attribute, opts|
21
+ opts.merge!(input_html: {
22
+ class: 'filter_row form-control'
23
+ })
24
+
25
+ f.filter attribute.to_sym, opts
26
+ end
27
+
28
+ buttons = content_tag :div, class: "buttons" do
29
+ f.submit('Filter', class: 'btn btn-primary') +
30
+ link_to('Clear', request.path, class: 'clear_filters_btn btn btn-secondary')
31
+ end
32
+
33
+ f.template.concat buttons
34
+ end
35
+ end
36
+
2
37
  def inside_layout(l, &block)
3
38
  content_for("#{l}_layout".to_sym, capture(&block))
4
39
  render(template: "layouts/#{l}")