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
data/lib/adminos.rb CHANGED
@@ -3,17 +3,38 @@ require 'rails'
3
3
  require 'jquery-fileupload-rails'
4
4
  require 'dotenv-rails'
5
5
  require 'babosa'
6
- require 'russian'
7
6
  require 'devise'
8
7
  require 'cancancan'
8
+ require 'ransack'
9
9
  require 'cocoon'
10
+ require 'simple_form'
10
11
 
11
12
  module Adminos
13
+
14
+ autoload :FormBuilder, 'adminos/form_builder'
15
+
16
+ class << self
17
+ attr_writer :configuration
18
+ end
19
+
20
+ def self.configuration
21
+ @configuration ||= Configuration.new
22
+ end
23
+
24
+ def self.reset
25
+ @configuration = Configuration.new
26
+ end
27
+
28
+ def self.configure
29
+ yield(configuration)
30
+ end
31
+
12
32
  Helpers = Module.new
13
33
  NestedSet = Module.new
14
34
  Controllers = Module.new
15
35
  StatefulLink = Module.new
16
36
 
37
+
17
38
  Path.require_tree 'adminos', except: %w[generators operations]
18
39
 
19
40
  class Engine < ::Rails::Engine
@@ -26,6 +47,7 @@ module Adminos
26
47
  initializer 'adminos.controller_helpers' do
27
48
  ActionController::Base.send :include, Controllers::Helpers
28
49
  ActionController::Base.send :include, Controllers::Resource
50
+ ActionController::Base.send :include, Controllers::Filters
29
51
  end
30
52
 
31
53
  initializer 'adminos.stateful_link' do
@@ -38,5 +60,3 @@ module Adminos
38
60
  end
39
61
  end
40
62
  end
41
-
42
- require 'adminos/extensions/nested_set'
@@ -26,6 +26,7 @@ module Adminos::Generators
26
26
  file = Dir.glob('db/migrate/*.rb').grep(/\d+_create_#{table_name}.rb$/).first
27
27
 
28
28
  return unless file
29
+
29
30
  inject_into_file file, file_content('migration.rb', true), after: /create_table.*\n/
30
31
 
31
32
  if drag_type?
@@ -62,6 +63,10 @@ module Adminos::Generators
62
63
  def locale_specific_actions
63
64
  return unless options.locale? || attributes.map(&:locale).any?
64
65
 
66
+ file = Dir.glob('db/migrate/*.rb').grep(/\d+_create_#{table_name}.rb$/).first
67
+ locale_attributes = attributes.map { |attr| attr.name if attr.locale }.compact
68
+ locale_attributes += %w(name nav_name meta_description meta_title)
69
+
65
70
  template 'locales/locale_fields.slim', "app/views/admin/#{table_name}/_locale_fields.slim"
66
71
  template 'locales/general_fields.slim', "app/views/admin/#{table_name}/_general_fields.slim" #unless attributes.map(&:locale).delete_if{|e| e == true}.blank?
67
72
  remove_file "app/views/admin/#{table_name}/_fields.slim"
@@ -69,17 +74,15 @@ module Adminos::Generators
69
74
  if File.exist?("app/models/#{file_name}.rb")
70
75
  inject_into_file "app/models/#{file_name}.rb", erb_file_content('locales/model.rb.erb'), before: /^\Snd\n/
71
76
  end
72
- comment_lines "app/models/#{file_name}.rb", /validates :name/
73
77
 
74
- if File.exist?("app/controllers/admin/#{table_name}_controller.rb")
75
- inject_into_file "app/controllers/admin/#{table_name}_controller.rb", " filter_by_locale: true,\n", before: /.*find_by_slug.*\n/
78
+ locale_attributes.each do |f|
79
+ gsub_file(file, /(t.string|t.text).+:(#{f})/, "t.jsonb :#{f}")
76
80
  end
77
81
 
78
- migration_template 'locales/migration.rb.erb', "db/migrate/add_translation_table_to_#{file_name}.rb"
82
+ comment_lines "app/models/#{file_name}.rb", /validates :name/
79
83
 
80
- unless options.seo?
81
- file = Dir.glob('db/migrate/*.rb').grep(/\d+_add_translation_table_to_#{file_name}.rb$/).first
82
- gsub_file(file, /.+(meta_description|meta_title).+/, '')
84
+ if File.exist?("app/controllers/admin/#{table_name}_controller.rb")
85
+ inject_into_file "app/controllers/admin/#{table_name}_controller.rb", " filter_by_locale: true,\n", before: /.*find_by_slug.*\n/
83
86
  end
84
87
  end
85
88
 
@@ -0,0 +1,39 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module Adminos::Generators
4
+ class FeedbackGenerator < Rails::Generators::Base
5
+ include ActiveRecord::Generators::Migration
6
+
7
+ desc 'Set up feedbacks'
8
+ source_root File.expand_path '../../templates/feedback', __FILE__
9
+
10
+ def auto
11
+ directory 'auto', '.', mode: :preserve
12
+ end
13
+
14
+ def route
15
+ insert_into_file "config/routes.rb", after: "namespace :admin do\n" do
16
+ <<~ROUT.indent(4)
17
+
18
+ resources :feedbacks, except: :show do
19
+ collection { post :batch_action }
20
+ end
21
+
22
+ ROUT
23
+ end
24
+ end
25
+
26
+ def migration
27
+ migration_template 'feedbacks_migration.rb', 'db/migrate/create_feedbacks.rb'
28
+ end
29
+
30
+ def sidebar_link
31
+ insert_into_file "app/views/shared/admin/_sidebar.slim", before: "\n = top_menu_item active: 'admin/settings#' do" do
32
+ <<~SLIM.indent(8)
33
+ = top_menu_item active: 'admin/feedbacks#' do
34
+ = link_to t('admin.feedbacks.actions.index.header'), admin_feedbacks_path, class: 'nav__link'
35
+ SLIM
36
+ end
37
+ end
38
+ end
39
+ end
@@ -53,11 +53,19 @@ module Adminos::Generators
53
53
 
54
54
  def localize_pages
55
55
  return unless options.pages?
56
+ file = Dir.glob('db/migrate/*.rb').grep(/\d+_create_pages.rb$/).first
57
+ model = 'app/models/page.rb'
56
58
 
57
- migration_template 'add_translation_table_to_page.rb', 'db/migrate/add_translation_table_to_page.rb'
58
- inject_into_file 'app/models/page.rb', file_content('page.rb'), before: /.*BEHAVIORS = .*/
59
- comment_lines 'app/models/page.rb', /validates :name/
60
- inject_into_file 'app/models/page.rb', ', :translations_attributes', after: /.*:parent_id, :published/
59
+ %w(name nav_name body meta_description meta_title).each do |f|
60
+ gsub_file(file, /(t.string|t.text).+:#{f}/, "t.jsonb :#{f}")
61
+ end
62
+
63
+ inject_into_file model, file_content('page.rb'), before: /.*BEHAVIORS = .*/
64
+
65
+ gsub_file(model, 'has_rich_text :content', 'I18n.available_locales.each { |locale| has_rich_text(:"content_#{locale}") }')
66
+
67
+ comment_lines model, /validates :name/
68
+ inject_into_file model, ', :translations_attributes', after: /.*:parent_id, :published/
61
69
  inject_into_file 'app/controllers/admin/pages_controller.rb', " filter_by_locale: true,\n", after: /.*[:sorted],\n/
62
70
  inject_into_file 'app/controllers/application_controller.rb', " before_action :check_page_name_locale, unless: -> { controller_path.split('/').first == 'admin' }", after: /.*before_action.*\n/
63
71
  remove_file 'app/views/admin/pages/_fields.slim'
@@ -67,6 +75,10 @@ module Adminos::Generators
67
75
  directory 'auto', '.'
68
76
  end
69
77
 
78
+ def setup_tolk
79
+ rake 'tolk:setup'
80
+ end
81
+
70
82
  private
71
83
 
72
84
  def available_locales
@@ -16,6 +16,7 @@ module Adminos::Generators
16
16
  class_option :locales, type: :string
17
17
  class_option :is_test, type: :boolean, default: false
18
18
  class_option :ci, type: :boolean, default: true, desc: 'Set up Gitlab CI'
19
+ class_option :search, type: :string, enum: %w[elastic pg_search], default: 'pg_search', desc: 'Set up Search'
19
20
 
20
21
  def questions
21
22
  @settings = {}
@@ -53,6 +54,10 @@ module Adminos::Generators
53
54
  append_file 'db/seeds.rb', file_content('prepare_settings.rb')
54
55
  end
55
56
 
57
+ def readme
58
+ append_file 'README.md', file_content('README.md')
59
+ end
60
+
56
61
  def templates
57
62
  template 'deploy.rb.erb', 'config/deploy.rb'
58
63
  template 'database.yml', 'config/database.yml'
@@ -91,10 +96,27 @@ module Adminos::Generators
91
96
  run 'bundle exec rails action_text:copy_migrations'
92
97
  end
93
98
 
99
+ def run_binstubs
100
+ run 'bundle binstubs puma'
101
+ end
102
+
94
103
  def install_adminos_assets
95
104
  run "yarn add adminos"
96
105
  end
97
106
 
107
+ def setup_search
108
+ case options[:search]
109
+ when 'elastic'
110
+ gsub_file 'config/initializers/adminos.rb', /config.search_engine.+/ do
111
+ 'config.search_engine = Adminos::Search::Elastic'
112
+ end
113
+
114
+ gsub_file 'Gemfile', "gem 'pg_search'", ''
115
+
116
+ inject_into_file 'Gemfile', "gem 'searchkick'\n", after: /gem 'adminos'.+\n/
117
+ end
118
+ end
119
+
98
120
  def install_devise
99
121
  return unless @settings[:install_devise]
100
122
  generate 'devise:install'
@@ -0,0 +1,34 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module Adminos::Generators
4
+ class ProfileGenerator < Rails::Generators::Base
5
+ include ActiveRecord::Generators::Migration
6
+
7
+ desc 'Set up admin profile page'
8
+ source_root File.expand_path '../../templates/profile', __FILE__
9
+
10
+ def auto
11
+ directory 'auto', '.', mode: :preserve
12
+ end
13
+
14
+ def route
15
+ insert_into_file "config/routes.rb", after: "resource :settings, only: [:edit, :update]\n" do
16
+ <<~ROUT.indent(6)
17
+ resource :profile, only: [:edit, :update]
18
+ ROUT
19
+ end
20
+ end
21
+
22
+ def sidebar_link
23
+ insert_into_file "app/views/shared/admin/_sidebar.slim", before: "\n = top_menu_item active: 'admin/settings#' do" do
24
+ <<~SLIM.indent(8)
25
+
26
+ = top_menu_item active: 'admin/profiles#' do
27
+ = link_to edit_admin_profile_path, class: 'nav__link' do
28
+ span.link.link--settings
29
+ = t('admin.profile.actions.index.header')
30
+ SLIM
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,38 @@
1
+
2
+ module Adminos::Generators
3
+ class SearchGenerator < Rails::Generators::NamedBase
4
+ desc 'Helps you setup your search.'
5
+
6
+ def configure_model
7
+ inject_into_class model_path, model do
8
+ <<~MODEL.indent(2)
9
+ include Adminos::Searchable
10
+
11
+ searchable
12
+ MODEL
13
+ end
14
+ end
15
+
16
+ def add_partial
17
+ insert_into_file partial_path, after: /collection_header\n/ do
18
+ <<~SLIM
19
+ = render 'shared/admin/search_form'
20
+ SLIM
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def model_path
27
+ "app/models/#{model.underscore}.rb"
28
+ end
29
+
30
+ def partial_path
31
+ "app/views/admin/#{model.underscore.pluralize}/index.slim"
32
+ end
33
+
34
+ def model
35
+ "#{file_path.tr('/', '_').singularize.classify}"
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,81 @@
1
+ require 'rails/generators/active_record'
2
+ require "adminos/generators/utilities"
3
+
4
+ module Adminos::Generators
5
+ class TwoFactorAuthGenerator < Rails::Generators::Base
6
+ include ActiveRecord::Generators::Migration
7
+ include Utilities
8
+
9
+ desc 'Set up 2fa for users'
10
+ source_root File.expand_path '../../templates/two_facto_auth', __FILE__
11
+
12
+ def auto
13
+ directory 'auto', '.', mode: :preserve
14
+ end
15
+
16
+ def bundle_dependencies
17
+ merge_gemfile_with('Gemfile')
18
+ install_dependencies
19
+ end
20
+
21
+ def generate_two_factor
22
+ generate 'devise_two_factor user OTP_SECRET_ENCRYPTION_KEY'
23
+ end
24
+
25
+ def routes
26
+ insert_into_file "config/routes.rb", after: "resource :profile, only: [:edit, :update]\n" do
27
+ <<~ROUT.indent(6)
28
+ resource :profile, only: [] do
29
+ member { post :toggle_two_factor }
30
+ end
31
+ ROUT
32
+ end
33
+
34
+ insert_into_file "config/routes.rb", after: "devise_for :users, skip: :omniauth_callbacks" do
35
+ <<~ROUT
36
+ ,
37
+ controllers: { sessions: 'users/sessions'}
38
+ ROUT
39
+ end
40
+ end
41
+
42
+ def add_toggle_two_factor_action
43
+ insert_into_file "app/controllers/admin/profiles_controller.rb", before: "\n private" do
44
+ <<~RUBY.indent(2)
45
+
46
+ def toggle_two_factor
47
+ if resource.otp_required_for_login
48
+ resource.update(otp_required_for_login: false)
49
+ else
50
+ resource.update(otp_required_for_login: true, otp_secret: User.generate_otp_secret)
51
+ end
52
+ redirect_to action: :edit
53
+ end
54
+ RUBY
55
+ end
56
+ end
57
+
58
+ def add_2fa_to_profile_page
59
+ insert_into_file "app/views/admin/profiles/edit.slim", after: "= f.input :current_password, hint: 'Введите текущий пароль'\n" do
60
+ <<~SLIM.indent(6)
61
+ = render '2fa', resource: resource
62
+ SLIM
63
+ end
64
+ end
65
+
66
+ def add_qrcode_helper
67
+ insert_into_file "app/helpers/application_helper.rb", after: "module ApplicationHelper\n" do
68
+ <<~RUBY.indent(2)
69
+ def google_authenticator_qrcode(devise_resource)
70
+ issuer = '' # TODO: issuer name
71
+ label = "\#{issuer}:\#{devise_resource.email}"
72
+ data = devise_resource.otp_provisioning_uri(label, issuer: issuer)
73
+ escaped_data = Rack::Utils.escape(data)
74
+ url = "https://chart.googleapis.com/chart?chs=200x200&chld=M|0&cht=qr&chl=\#{escaped_data}"
75
+ image_tag(url, alt: 'Google Authenticator QRCode')
76
+ end
77
+ RUBY
78
+ end
79
+ end
80
+ end
81
+ end
@@ -13,7 +13,7 @@
13
13
  = f.input :<%= attribute.name %>
14
14
  <% end -%>
15
15
 
16
- <% unless options.seo? -%>
16
+ <% if options.seo? -%>
17
17
  .f__fieldset
18
18
  .f__legend= t 'labels.admin.legend.seo'
19
19
  = f.input :meta_title
@@ -1,10 +1,13 @@
1
1
  .f__fieldset
2
- = f.input :name<%= "\n = f.input :nav_name" if options.type == 'section' %>
2
+ = f.input :name, locale: locale
3
+ <%= "\n = f.input :nav_name, locale: locale" if options.type == 'section' %>
3
4
  <% attributes.each do |attribute| -%>
4
- <%= " = f.input :#{attribute.name}\n" if attribute.locale -%>
5
+ <%= " = f.input :#{attribute.name}, locale: locale\n" if attribute.locale -%>
5
6
  <% end -%>
6
7
 
8
+ <% if options.seo? -%>
7
9
  .f__fieldset
8
10
  .f__legend= t 'labels.admin.legend.seo'
9
- = f.input :meta_title
10
- = f.input :meta_description, as: :string
11
+ = f.input :meta_title, locale: locale
12
+ = f.input :meta_description, as: :string, locale: locale
13
+ <% end -%>
@@ -1,6 +1,5 @@
1
+ extend Mobility
1
2
 
2
- translates :name, <%= attributes.map{|a| ":#{a.name}, " if a.locale }.compact.join %><%= ':nav_name, ' if options.type == 'section' %>:meta_description, :meta_title
3
-
4
- accepts_nested_attributes_for :translations
3
+ translates :name, <%= attributes.map{|a| ":#{a.name}, " if a.locale }.compact.join %><%= ':nav_name, ' if options.type == 'section' %><%= ':meta_description, :meta_title, ' if options.seo? %>locale_accessors: true, ransack: true
5
4
 
6
5
  validates_with LocaleValidator
@@ -4,7 +4,7 @@ variables:
4
4
  before_script:
5
5
  - rvm install $(cat .ruby-version)
6
6
  - rvm use $(cat .ruby-version)
7
- - gem install bundler --no-ri --no-rdoc
7
+ - gem install bundler --no-document
8
8
  - bundle config build.pg --with-pg-config=/usr/pgsql-9.4/bin/pg_config
9
9
  - bin/setup
10
10
 
@@ -0,0 +1,17 @@
1
+ class Admin::FeedbacksController < Admin::BaseController
2
+ authorize_resource
3
+
4
+ resource( Feedback,
5
+ collection_scope: [:sorted],
6
+ location: proc { params[:stay_in_place] ?
7
+ edit_polymorphic_path([:admin, resource]) :
8
+ polymorphic_path([:admin, resource.class]) })
9
+
10
+ private
11
+
12
+ alias_method :collection_orig, :collection
13
+ def collection
14
+ @collection ||= collection_orig
15
+ .page(params[:page]).per(settings.per_page)
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ class FeedbacksController < ApplicationController
2
+ def create
3
+ @feedback = Feedback.create(feedback_params)
4
+ end
5
+
6
+ private
7
+
8
+ def feedback_params
9
+ params.require(:feedback).permit(:name, :phone, :email, :message)
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ class Feedback < ActiveRecord::Base
2
+
3
+ scope :sorted, -> { order('created_at DESC') }
4
+
5
+ validates :name, :message, presence: true
6
+ end
@@ -0,0 +1,5 @@
1
+ .f__fieldset
2
+ = f.input :name
3
+ = f.input :email
4
+ = f.input :phone
5
+ = f.input :message
@@ -0,0 +1,28 @@
1
+ - collection_title
2
+ = collection_header
3
+
4
+ - if collection.present?
5
+ - list = capture do
6
+ /= render partial: 'objects', object: collection
7
+ .table-list
8
+ table.table.table-hover.table-sm.table--feedback
9
+ tbody
10
+ - collection.each do |object|
11
+ tr
12
+ td.table__details
13
+ = object.name
14
+ span title="#{resource_class.human_attribute_name(:email)}"= link_to object.email, "mailto:#{object.email}"
15
+ span title="#{resource_class.human_attribute_name(:phone)}"= object.phone
16
+ td.table__text
17
+ = simple_format(object.message)
18
+ td.table-list__controls
19
+ = object_link_edit(object)
20
+ td.table-list__check
21
+ = admin_cb(object)
22
+
23
+ - if controller.respond_to?(:batch_action)
24
+ = batch_actions_tag publication: (collection.respond_to?(:set_each_published_on)),
25
+ nav_publication: (collection.respond_to?(:set_nav_published_on)) do
26
+ = list
27
+ - else
28
+ = list
@@ -0,0 +1,13 @@
1
+ class CreateFeedbacks < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :feedbacks do |t|
4
+ t.string :name
5
+
6
+ t.string :email
7
+ t.string :phone
8
+ t.text :message
9
+
10
+ t.timestamps null: false
11
+ end
12
+ end
13
+ end
@@ -1,4 +1,4 @@
1
1
  .f__fieldset
2
2
  <% attributes.select(&:locale).each do |attribute| -%>
3
- <%= " = f.input :#{attribute.name}\n" -%>
3
+ <%= " = f.input :#{attribute.name} locale: locale\n" -%>
4
4
  <% end -%>
@@ -1,6 +1,5 @@
1
+ extend Mobility
1
2
 
2
- translates :name, <%= attributes.map{|a| ":#{a.name}" }.compact.join(', ') %>
3
-
4
- accepts_nested_attributes_for :translations
3
+ translates :name, <%= attributes.map{|a| ":#{a.name}" }.compact.join(', ') %>, locale_accessors: true, ransack: true
5
4
 
6
5
  validates_with LocaleValidator
@@ -1 +1,6 @@
1
- gem 'globalize'
1
+ gem 'mobility'
2
+ gem 'mobility-ransack', '~> 0.2.2'
3
+ gem 'devise-i18n'
4
+ gem 'kaminari-i18n'
5
+ gem 'rails-i18n'
6
+ gem 'tolk'
@@ -13,9 +13,13 @@ class LocaleValidator < ActiveModel::Validator
13
13
 
14
14
  def validations(field, record)
15
15
  validate_name = false
16
+
16
17
  I18n.available_locales.each do |locale|
17
- validate_name = true unless record.translation_for(locale).send(field).blank?
18
+ Mobility.with_locale(locale) do
19
+ validate_name = true unless record.send(field).blank?
20
+ end
18
21
  end
22
+
19
23
  validate_name = true if record.send(field).presence
20
24
 
21
25
  record.errors.add(field, 'Укажите Название хотя бы в одной локали') unless validate_name
@@ -12,8 +12,4 @@ ul.nav.nav-tabs.with-togglable-navigation
12
12
  .tab-content
13
13
  - I18n.available_locales.each_with_index do |locale, i|
14
14
  .tab-pane id="pill_#{locale}" class=('active' if locale == :ru)
15
- - if locale == I18n.default_locale
16
- = render 'locale_fields', locale: locale, f: f
17
- - else
18
- = f.globalize_fields_for locale, wrapper: :admin do |g|
19
- = render 'locale_fields', locale: locale, f: g
15
+ = render 'locale_fields', locale: locale, f: f
@@ -1,13 +1,13 @@
1
1
  .f__fieldset
2
- = f.input :name
3
- = f.input :nav_name
2
+ = f.input :name, locale: locale
3
+ = f.input :nav_name, locale: locale
4
4
 
5
- = f.rich_text_area :content
5
+ = f.rich_text_area "content_#{locale}"
6
6
  / = f.input :body
7
7
  /.kaya-please
8
8
  = f.input_field :body, as: :text, id: 'kaya-editor', value: f.object.read_attribute(:body)
9
9
 
10
10
  .f__fieldset
11
11
  .f__legend= t 'labels.admin.legend.seo'
12
- = f.input :meta_title
13
- = f.input :meta_description, as: :string
12
+ = f.input :meta_title, locale: locale
13
+ = f.input :meta_description, as: :string, locale: locale