ab_admin 0.8.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +11 -5
  4. data/app/assets/javascripts/ab_admin/components/admin_assets.js.coffee +0 -25
  5. data/app/assets/javascripts/ab_admin/components/google_translate.js.coffee +3 -5
  6. data/app/assets/javascripts/ab_admin/components/in_place_edit.js.coffee +33 -25
  7. data/app/assets/javascripts/ab_admin/core/batch_actions.js.coffee +1 -1
  8. data/app/assets/javascripts/ab_admin/core/columns_hider.js.coffee +24 -23
  9. data/app/assets/javascripts/ab_admin/core/init.js.coffee +7 -2
  10. data/app/assets/javascripts/ab_admin/core/search_form.js.coffee +1 -7
  11. data/app/assets/javascripts/ab_admin/core/ui_utils.js.coffee +23 -7
  12. data/app/assets/javascripts/ab_admin/core/utils.js.coffee +16 -2
  13. data/app/assets/javascripts/ab_admin/inputs/datetime_input.js.coffee +1 -0
  14. data/app/assets/javascripts/ab_admin/main.js +3 -4
  15. data/app/assets/stylesheets/ab_admin/bootstrap_and_overrides.scss +71 -25
  16. data/app/assets/stylesheets/ab_admin/components/_base.scss +21 -1
  17. data/app/assets/stylesheets/ab_admin/components/_colored_tabs.scss +1 -1
  18. data/app/assets/stylesheets/ab_admin/components/_form.scss +16 -18
  19. data/app/assets/stylesheets/ab_admin/components/_grid_view.scss +2 -2
  20. data/app/assets/stylesheets/ab_admin/components/_locale_tabs.scss +11 -23
  21. data/app/assets/stylesheets/ab_admin/components/_navigation.scss +7 -11
  22. data/app/assets/stylesheets/ab_admin/components/_table_view.scss +85 -11
  23. data/app/assets/stylesheets/ab_admin/components/_tooltip.scss +81 -0
  24. data/app/assets/stylesheets/ab_admin/components/_tree_view.scss +1 -1
  25. data/app/assets/stylesheets/ab_admin/devise.scss +2 -2
  26. data/app/assets/stylesheets/ab_admin/fileupload.scss +2 -9
  27. data/app/assets/stylesheets/ab_admin/main.scss +1 -2
  28. data/app/controllers/admin/assets_controller.rb +1 -1
  29. data/app/controllers/admin/base_controller.rb +133 -149
  30. data/app/controllers/admin/dashboards_controller.rb +2 -2
  31. data/app/controllers/admin/locators_controller.rb +8 -6
  32. data/app/controllers/admin/manager_controller.rb +19 -49
  33. data/app/controllers/admin/static_pages_controller.rb +0 -4
  34. data/app/controllers/admin/structures_controller.rb +2 -2
  35. data/app/views/ab_admin/devise/sessions/new.html.slim +2 -0
  36. data/app/views/admin/assets/batch_edit.html.slim +3 -2
  37. data/app/views/admin/base/_search_layout.html.slim +7 -6
  38. data/app/views/admin/base/create.js.erb +6 -3
  39. data/app/views/admin/base/edit.js.erb +1 -1
  40. data/app/views/admin/base/index.html.slim +4 -4
  41. data/app/views/admin/base/new.js.erb +1 -1
  42. data/app/views/admin/base/update.js.erb +7 -2
  43. data/app/views/admin/fileupload/_asset_templates.html.slim +1 -2
  44. data/app/views/admin/fileupload/_image.html.slim +1 -2
  45. data/app/views/admin/locators/edit.html.slim +7 -6
  46. data/app/views/admin/manager/_map.html.slim +4 -0
  47. data/app/views/admin/manager/_show_table.html.slim +1 -1
  48. data/app/views/admin/manager/_stats.html.slim +4 -0
  49. data/app/views/admin/manager/_table.html.slim +7 -4
  50. data/app/views/admin/shared/_content_actions.html.slim +35 -30
  51. data/app/views/admin/shared/_flash.html.slim +5 -4
  52. data/app/views/admin/shared/_locale_tabs.html.slim +2 -2
  53. data/app/views/admin/shared/_main_menu.html.slim +1 -1
  54. data/app/views/admin/shared/_save_buttons.html.slim +10 -1
  55. data/app/views/admin/structures/_form.html.slim +1 -1
  56. data/app/views/admin/users/_form.html.slim +3 -3
  57. data/app/views/admin/users/_search_form.html.slim +1 -1
  58. data/app/views/layouts/admin/_footer.html.slim +0 -1
  59. data/app/views/layouts/admin/_navigation.html.slim +1 -1
  60. data/app/views/layouts/admin/application.html.slim +2 -2
  61. data/config/locales/de.yml +1 -2
  62. data/config/locales/en.yml +9 -15
  63. data/config/locales/it.yml +1 -0
  64. data/config/locales/ru.yml +0 -1
  65. data/config/locales/uk.yml +0 -1
  66. data/db/migrate/20130101000001_create_users.rb +1 -4
  67. data/db/migrate/20130101000003_create_assets.rb +1 -1
  68. data/db/migrate/20130101000004_create_headers.rb +5 -5
  69. data/db/migrate/20130101000005_create_static_pages.rb +2 -5
  70. data/db/migrate/20130101000006_create_structures.rb +1 -1
  71. data/db/migrate/20130101000007_base_translations.rb +43 -12
  72. data/db/migrate/20130101000008_create_admin_comments.rb +2 -7
  73. data/db/migrate/20130101000009_create_tracks.rb +4 -8
  74. data/lib/ab_admin/abstract_resource.rb +6 -5
  75. data/lib/ab_admin/carrierwave/base_uploader.rb +87 -75
  76. data/lib/ab_admin/carrierwave/glue.rb +0 -5
  77. data/lib/ab_admin/concerns/admin_addition.rb +15 -27
  78. data/lib/ab_admin/concerns/translations_macro.rb +97 -0
  79. data/lib/ab_admin/concerns/utilities.rb +2 -2
  80. data/lib/ab_admin/config/base.rb +27 -4
  81. data/lib/ab_admin/controllers/callbacks.rb +3 -26
  82. data/lib/ab_admin/core_ext/array.rb +1 -50
  83. data/lib/ab_admin/core_ext/hash.rb +2 -31
  84. data/lib/ab_admin/core_ext/other.rb +0 -6
  85. data/lib/ab_admin/core_ext/string.rb +1 -86
  86. data/lib/ab_admin/devise.rb +7 -0
  87. data/lib/ab_admin/engine.rb +2 -1
  88. data/lib/ab_admin/hooks/ckeditor_lazy.rb +13 -0
  89. data/lib/ab_admin/hooks/will_paginate_id_prefetch.rb +8 -6
  90. data/lib/ab_admin/hooks/will_paginate_no_uri.rb +1 -1
  91. data/lib/ab_admin/i18n_tools/google_translate.rb +3 -1
  92. data/lib/ab_admin/i18n_tools/model_translator.rb +1 -1
  93. data/lib/ab_admin/menu/base_group.rb +0 -1
  94. data/lib/ab_admin/menu/group.rb +2 -4
  95. data/lib/ab_admin/menu/item.rb +4 -8
  96. data/lib/ab_admin/models/asset.rb +7 -10
  97. data/lib/ab_admin/models/header.rb +2 -2
  98. data/lib/ab_admin/models/locator.rb +29 -3
  99. data/lib/ab_admin/models/settings.rb +2 -2
  100. data/lib/ab_admin/models/structure.rb +3 -3
  101. data/lib/ab_admin/models/track.rb +15 -3
  102. data/lib/ab_admin/models/user.rb +12 -48
  103. data/lib/ab_admin/utils/csv_document.rb +8 -6
  104. data/lib/ab_admin/utils/eval_helpers.rb +0 -13
  105. data/lib/ab_admin/utils/logger.rb +12 -2
  106. data/lib/ab_admin/utils/mysql.rb +2 -3
  107. data/lib/ab_admin/utils/xls_document.rb +18 -18
  108. data/lib/ab_admin/utils.rb +0 -5
  109. data/lib/ab_admin/version.rb +1 -1
  110. data/lib/ab_admin/views/admin_helpers.rb +43 -28
  111. data/lib/ab_admin/views/admin_navigation_helpers.rb +18 -16
  112. data/lib/ab_admin/views/form_builder.rb +7 -5
  113. data/lib/ab_admin/views/helpers.rb +0 -9
  114. data/lib/ab_admin/views/inputs/ckeditor_input.rb +1 -5
  115. data/lib/ab_admin/views/manager_helpers.rb +15 -6
  116. data/lib/ab_admin/views/search_form_builder.rb +13 -13
  117. data/lib/ab_admin/views/will_paginate_bootstrap_renderer.rb +60 -0
  118. data/lib/ab_admin.rb +44 -32
  119. data/lib/generators/ab_admin/glob/glob_generator.rb +4 -5
  120. data/lib/generators/ab_admin/glob/templates/migration.erb +10 -7
  121. data/lib/generators/ab_admin/install/templates/config/ab_admin.rb.erb +1 -1
  122. data/lib/generators/ab_admin/install/templates/models/user.rb +1 -13
  123. data/lib/generators/ab_admin/install/templates/spec/spec_helper.rb +0 -1
  124. data/lib/generators/ab_admin/install/templates/spec/support/database_cleaner.rb +8 -11
  125. data/lib/generators/ab_admin/install/templates/uploaders/attachment_file_uploader.rb +1 -1
  126. data/lib/generators/ab_admin/install/templates/uploaders/avatar_uploader.rb +1 -1
  127. data/lib/generators/ab_admin/install/templates/uploaders/picture_uploader.rb +16 -3
  128. data/lib/generators/ab_admin/model/model_generator.rb +3 -4
  129. data/lib/generators/ab_admin/model/templates/resource.erb +5 -2
  130. data/lib/generators/ab_admin/resource/resource_generator.rb +0 -4
  131. data/lib/generators/ab_admin/resource/templates/controller.erb +2 -9
  132. data/lib/tasks/assets.rake +5 -5
  133. metadata +45 -85
  134. data/app/assets/images/admin/Jcrop.gif +0 -0
  135. data/app/assets/images/admin/flags/de.png +0 -0
  136. data/app/assets/images/admin/flags/en.png +0 -0
  137. data/app/assets/images/admin/flags/es.png +0 -0
  138. data/app/assets/images/admin/flags/fr.png +0 -0
  139. data/app/assets/images/admin/flags/it.png +0 -0
  140. data/app/assets/images/admin/flags/ja.png +0 -0
  141. data/app/assets/images/admin/flags/pl.png +0 -0
  142. data/app/assets/images/admin/flags/ru.png +0 -0
  143. data/app/assets/images/admin/flags/uk.png +0 -0
  144. data/app/assets/javascripts/ab_admin/components/croppable_image.js.coffee +0 -33
  145. data/app/assets/stylesheets/ab_admin/components/_columns_hider.scss +0 -5
  146. data/app/assets/stylesheets/ab_admin/components/_perms.scss +0 -39
  147. data/app/views/admin/shared/_columns_hider.html.slim +0 -9
  148. data/lib/ab_admin/hooks/globalize_locale_suffix_accessors.rb +0 -25
  149. data/lib/ab_admin/hooks/globalize_valid_locale.rb +0 -9
  150. data/lib/generators/ab_admin/ckeditor_assets/ckeditor_assets_generator.rb +0 -19
  151. data/lib/generators/template.rb +0 -96
@@ -6,17 +6,14 @@ module AbAdmin
6
6
  included do
7
7
  has_one :avatar, as: :assetable, dependent: :destroy, autosave: true
8
8
 
9
- scope :managers, -> { where(user_role_id: [::UserRoleType.admin.id, ::UserRoleType.moderator.id]) }
10
9
  scope :active, -> { where(locked_at: nil) }
11
10
  scope :admin, proc { includes(:avatar) }
12
11
 
13
- after_initialize :init
14
- before_validation :generate_login
15
- before_validation :set_default_role, unless: :user_role_id?
16
-
17
- validate :check_role
18
-
19
12
  enumerated_attribute :user_role_type, id_attribute: :user_role_id, class: ::UserRoleType
13
+ delegate *UserRoleType.codes.map{|code| "#{code}?" }, to: :user_role_type
14
+ end
15
+
16
+ def admin_menu_builder
20
17
  end
21
18
 
22
19
  def name
@@ -40,6 +37,10 @@ module AbAdmin
40
37
  active_for_authentication?
41
38
  end
42
39
 
40
+ def admin_access?
41
+ admin? || moderator?
42
+ end
43
+
43
44
  def generate_password!
44
45
  raw_password = AbAdmin.test_env? ? '654321' : AbAdmin.friendly_token
45
46
  self.password = self.password_confirmation = raw_password
@@ -47,47 +48,10 @@ module AbAdmin
47
48
  raw_password
48
49
  end
49
50
 
50
- def admin_access?
51
- moderator?
52
- end
53
-
54
- def default?
55
- has_role?(:default)
56
- end
57
-
58
- def redactor?
59
- has_role?(:redactor)
60
- end
61
-
62
- def moderator?
63
- has_role?(:admin) || has_role?(:moderator)
64
- end
65
-
66
- def admin?
67
- has_role?(:admin)
68
- end
69
-
70
- def has_role?(role_name)
71
- user_role_type.code == role_name
72
- end
73
-
74
- def set_default_role
75
- self.user_role_id ||= ::UserRoleType.default.id
76
- end
77
-
78
- protected
79
-
80
- def generate_login
81
- self.login ||= begin
82
- unless email.blank?
83
- tmp_login = email.split('@').first
84
- tmp_login.parameterize.downcase.gsub(/[^A-Za-z0-9-]+/, '-').gsub(/-+/, '-')
85
- end
86
- end
87
- end
88
-
89
- def check_role
90
- errors.add(:user_role_id, :invalid) unless ::UserRoleType.valid?(user_role_id)
51
+ def password_required?
52
+ return true if password.present?
53
+ return false if persisted? && password.blank?
54
+ super
91
55
  end
92
56
  end
93
57
  end
@@ -3,8 +3,6 @@ require 'csv'
3
3
  module AbAdmin
4
4
  module Utils
5
5
  class CsvDocument
6
- include AbAdmin::Utils::EvalHelpers
7
-
8
6
  def initialize(source, options = {})
9
7
  @source = source
10
8
  @options = options
@@ -27,12 +25,17 @@ module AbAdmin
27
25
  @filename ||= [@options[:filename] || "#{@klass.model_name.plural}-#{Time.now.strftime('%Y-%m-%d')}", '.csv'].join
28
26
  end
29
27
 
30
- def render
28
+ def render(context=nil, options={})
31
29
  ::CSV.generate(col_sep: @options[:column_separator] || ',') do |csv|
32
30
  csv << columns_names
33
31
 
34
- each_record do |item|
35
- csv << column_data.map { |column| AbAdmin.pretty_data call_method_or_proc_on(item, column, exec: false) }
32
+ I18n.with_locale options[:locale] do
33
+ each_record do |item|
34
+ csv << column_data.map do |column|
35
+ value = column.is_a?(Symbol) ? item.public_send(column) : context.instance_exec(item, &column)
36
+ AbAdmin.pretty_data value
37
+ end
38
+ end
36
39
  end
37
40
  end
38
41
  end
@@ -60,7 +63,6 @@ module AbAdmin
60
63
  @source.class
61
64
  end
62
65
  end
63
-
64
66
  end
65
67
  end
66
68
  end
@@ -83,19 +83,6 @@ module AbAdmin
83
83
  raise ArgumentError, 'Methods must be a symbol denoting the method to call, a block to be invoked, or a string to be evaluated'
84
84
  end
85
85
  end
86
-
87
- def call_method_or_proc_on(obj, symbol_or_proc, options = {})
88
- exec = options[:exec].nil? ? true : options[:exec]
89
- case symbol_or_proc
90
- when String
91
- ActiveSupport::Deprecation.warn('`call_method_or_proc_on` don\'t accept method name as String, use Symbol instead') if symbol_or_proc =~ /\A\w+\z/
92
- symbol_or_proc
93
- when Symbol
94
- obj.public_send(symbol_or_proc.to_sym, *options[:attrs])
95
- when Proc
96
- exec ? obj.instance_exec(&symbol_or_proc) : symbol_or_proc.call(obj)
97
- end
98
- end
99
86
  end
100
87
  end
101
88
  end
@@ -8,11 +8,21 @@ module AbAdmin
8
8
  error("#{e.class} #{message}\n#{backtrace}\n\n")
9
9
  end
10
10
 
11
+ def puts(msg)
12
+ debug msg
13
+ end
14
+
11
15
  def reopen
12
16
  @logdev = LogDevice.new(@logdev.filename)
13
17
  end
14
18
  end
15
19
 
20
+ class BasicFormatter
21
+ def call(severity, time, _, msg)
22
+ "#{msg}\n"
23
+ end
24
+ end
25
+
16
26
  class Formatter
17
27
  FORMAT = "[%s] %5s %s\n".freeze
18
28
  DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%3N'.freeze
@@ -22,9 +32,9 @@ module AbAdmin
22
32
  end
23
33
  end
24
34
 
25
- def self.for_file(filename)
35
+ def self.for_file(filename, formatter: nil)
26
36
  logger = ExtendedLogger.new(Rails.root.join('log', filename))
27
- logger.formatter = Formatter.new
37
+ logger.formatter = formatter || Formatter.new
28
38
  logger
29
39
  end
30
40
  end
@@ -14,14 +14,13 @@ module AbAdmin
14
14
 
15
15
  # remove duplicate records by columns
16
16
  def remove_duplicates(*cols, deleted_id_order: '<')
17
- conds = cols.map { |col| "#{table_name}.#{col} IS NOT NULL AND #{table_name}.#{col} = t.#{col}" }.join(' AND ')
17
+ condition_sql = cols.map { |col| "#{table_name}.#{col} IS NOT NULL AND #{table_name}.#{col} = t.#{col}" }.join(' AND ')
18
18
  query = <<-SQL
19
- DELETE FROM #{table_name} USING #{table_name}, #{table_name} AS t WHERE #{table_name}.id #{deleted_id_order} t.id AND #{conds}
19
+ DELETE FROM #{table_name} USING #{table_name}, #{table_name} AS t WHERE #{table_name}.id #{deleted_id_order} t.id AND #{condition_sql}
20
20
  SQL
21
21
  connection.execute(query)
22
22
  end
23
23
 
24
-
25
24
  # Disables key updates for model table
26
25
  def disable_keys
27
26
  connection.execute("ALTER TABLE #{quoted_table_name} DISABLE KEYS")
@@ -12,8 +12,6 @@ module AbAdmin
12
12
  end
13
13
 
14
14
  class XlsDocument
15
- include AbAdmin::Utils::EvalHelpers
16
-
17
15
  def initialize(source, options = {})
18
16
  @source = source
19
17
  @options = options
@@ -49,25 +47,27 @@ module AbAdmin
49
47
  @filename ||= [@options[:filename] || "#{@klass.model_name.plural}-#{Time.now.strftime('%Y-%m-%d')}", '.xlsx'].join
50
48
  end
51
49
 
52
- def render
50
+ def render(context, options={})
53
51
  date_format = workbook.add_format(num_format: 'dd.mm.yyyy')
54
52
  time_format = workbook.add_format(num_format: 'dd.mm.yyyy HH:MM')
55
53
 
56
- each_with_index do |item, index|
57
- row = index + 1
58
-
59
- column_data.each_with_index do |column, num|
60
- value = call_method_or_proc_on(item, column, exec: false)
61
-
62
- case value
63
- when Date
64
- worksheet.write_string(row, num, value.strftime('%Y-%m-%dT'), date_format)
65
- when DateTime, Time
66
- worksheet.write_date_time(row, num, value.strftime('%Y-%m-%dT%H:%M:%S.%L'), time_format)
67
- when String
68
- worksheet.write_string(row, num, value)
69
- else
70
- worksheet.write(row, num, AbAdmin.pretty_data(value))
54
+ I18n.with_locale options[:locale] do
55
+ each_with_index do |item, index|
56
+ row = index + 1
57
+
58
+ column_data.each_with_index do |column, num|
59
+ value = column.is_a?(Symbol) ? item.public_send(column) : context.instance_exec(item, &column)
60
+
61
+ case value
62
+ when Date
63
+ worksheet.write_string(row, num, value.strftime('%Y-%m-%dT'), date_format)
64
+ when DateTime, Time
65
+ worksheet.write_date_time(row, num, value.strftime('%Y-%m-%dT%H:%M:%S.%L'), time_format)
66
+ when String
67
+ worksheet.write_string(row, num, value)
68
+ else
69
+ worksheet.write(row, num, AbAdmin.pretty_data(value))
70
+ end
71
71
  end
72
72
  end
73
73
  end
@@ -1,10 +1,5 @@
1
1
  module AbAdmin
2
2
  module Utils
3
- autoload :CSVBuilder, 'ab_admin/utils/csv_builder'
4
- autoload :EvalHelpers, 'ab_admin/utils/eval_helpers'
5
- autoload :Logger, 'ab_admin/utils/logger'
6
- autoload :Mysql, 'ab_admin/utils/mysql'
7
-
8
3
  def all_models
9
4
  Kernel.suppress_warnings do
10
5
  Dir.glob(Rails.root.to_s + '/app/models/**/*.rb').reject { |path| path =~ /concerns|shared/ }.each { |file| require file }
@@ -1,3 +1,3 @@
1
1
  module AbAdmin
2
- VERSION = '0.8.3'
2
+ VERSION = '0.10.0'
3
3
  end
@@ -1,14 +1,16 @@
1
1
  module AbAdmin
2
2
  module Views
3
3
  module AdminHelpers
4
-
5
4
  def admin_form_for(object, *args, &block)
6
5
  record = Array(object).last
7
6
  record.fallbacks_for_empty_translations = false if record.respond_to?(:fallbacks_for_empty_translations)
8
7
  options = args.extract_options!
8
+ options[:wrapper] = :bootstrap
9
9
  options[:remote] = true if request.xhr?
10
10
  options[:html] ||= {}
11
- options[:html][:class] ||= 'form-horizontal'
11
+ options[:html][:class] = Array(options[:html][:class])
12
+ options[:html][:class] << 'form-horizontal' if options[:html][:class].empty?
13
+ options[:html][:class] << 'save-error' if Array(object).last.errors.of_kind?(:base, :changed)
12
14
  options[:builder] ||= ::AbAdmin::Views::FormBuilder
13
15
  options[:html]['data-id'] = record.id
14
16
  if controller_name == 'manager' && resource_class == Array(object).last.class
@@ -21,11 +23,11 @@ module AbAdmin
21
23
  end
22
24
  end
23
25
 
24
- def editable_bool(item, attr, label: nil)
26
+ def editable_bool(item, attr, label: nil, wrapper_class: nil)
25
27
  url = "/admin/#{item.class.model_name.plural}/#{item.id}.json"
26
28
  html = check_box_tag("#{item.class.model_name.singular}[#{attr}]", '1', item.send(attr), class: 'js-auto-submit-checkbox', data: {url: url})
27
29
  html = content_tag(:label, "#{label}&nbsp;#{html}".html_safe) if label
28
- content_tag :div, html, class: 'auto-submit-checkbox-wrap white-space-nowrap'
30
+ content_tag :div, html, class: ['auto-submit-checkbox-wrap', 'white-space-nowrap', ('tool' unless label), wrapper_class], title: attr
29
31
  end
30
32
 
31
33
  def admin_editable(item, attr, opts=nil)
@@ -78,11 +80,11 @@ module AbAdmin
78
80
  value: opts[:value] || item[attr],
79
81
  title: opts[:title] || item[attr]
80
82
  }
81
- link_to html_title, '#', class: "editable #{opts[:class]}", data: data.update(opts[:data] || {})
83
+ link_to html_title, '#', class: "editable #{opts[:class]}", placeholder: opts[:placeholder], data: data.update(opts[:data] || {})
82
84
  end
83
85
 
84
86
  def options_for_ckeditor(options = {})
85
- {width: 930, height: 200, toolbar: 'VeryEasy', namespace: ''}.update(options)
87
+ {width: 930, height: 200, namespace: ''}.update(options)
86
88
  end
87
89
 
88
90
  def admin_tree_item(item)
@@ -97,13 +99,13 @@ module AbAdmin
97
99
  def admin_layout_css
98
100
  css = []
99
101
  css << 'content_with_sidebar' if settings[:sidebar] || content_for?(:sidebar)
100
- css << 'well' if settings[:well] && current_index_view != 'tree'
101
- css << "#{current_index_view}_view"
102
+ css << 'well' if !@settings[:well].is_a?(FalseClass) && (collection_action? || %w(show history).include?(action_name)) && @settings[:current_index_view] != :tree
103
+ css << "#{settings[:current_index_view]}_view"
102
104
  css
103
105
  end
104
106
 
105
107
  def admin_title
106
- base = @breadcrumbs ? @breadcrumbs.map_val(:name).reverse : []
108
+ base = @breadcrumbs ? @breadcrumbs.map{|b| b[:name] }.reverse : []
107
109
  base << @page_title || 'Ab Admin'
108
110
  base.join(' - ')
109
111
  end
@@ -123,18 +125,27 @@ module AbAdmin
123
125
  %(<span class="badge #{css}">#{text}</span>).html_safe
124
126
  end
125
127
 
126
- def icon(name, white=false)
127
- "<i class='icon-#{name} #{'icon-white' if white}'></i> ".html_safe
128
+ def icon(name, white=false, title: nil)
129
+ title_html = %( title="#{h(title)}") if title
130
+ "<i class='icon-#{name}#{' icon-white' if white}#{' tool' if title}'#{title_html}></i> ".html_safe
131
+ end
132
+
133
+ def locale_flag(code)
134
+ (AbAdmin.locale_to_country_code[code] || code).to_s[0..1].upcase.tr('A-Z', '🇦-🇿')
128
135
  end
129
136
 
130
137
  def admin_pretty_data(object)
131
138
  case object
132
- when String, Integer, BigDecimal, Float
139
+ when Integer, BigDecimal, Float
133
140
  object
141
+ when String
142
+ object.html_safe? ? object : object.no_html.gsub("\n", '<br/>').html_safe
134
143
  when TrueClass, FalseClass
135
144
  color_bool(object)
136
- when Date, DateTime, Time, ActiveSupport::TimeWithZone
137
- I18n.l(object, format: :long)
145
+ when Date
146
+ I18n.l(object, format: AbAdmin.date_format)
147
+ when DateTime, Time, ActiveSupport::TimeWithZone
148
+ I18n.l(object, format: AbAdmin.datetime_format)
138
149
  when NilClass
139
150
  ''
140
151
  when ActiveRecord::Base
@@ -167,10 +178,6 @@ module AbAdmin
167
178
  image_tag_if(item.send(assoc).try(:url, size))
168
179
  end
169
180
 
170
- def per_page_variants
171
- AbAdmin.per_page_variants.map{|variant| [variant, max_per_page].min }.uniq
172
- end
173
-
174
181
  # input_set 'title', legend_class: 'do_sort', label_class: 'label-info' do
175
182
  def input_set(title, options={}, &block)
176
183
  options.reverse_merge!(class: "inputs well well-small clearfix #{options.delete(:legend_class) || 'do_sort'}", id: options.delete(:legend_id))
@@ -179,6 +186,11 @@ module AbAdmin
179
186
  content_tag(:div, html, options)
180
187
  end
181
188
 
189
+ def copy_btn(text, btn_text: nil, tooltip: false)
190
+ return if text.blank?
191
+ content_tag(:div, "#{icon('share')} #{btn_text}".html_safe, 'data-clipboard-text' => text, class: ['btn', 'btn-mini', 'js-copy', ('tool' if tooltip)], title: (text.no_html if tooltip))
192
+ end
193
+
182
194
  def ha(attr)
183
195
  resource_class.han(attr)
184
196
  end
@@ -187,16 +199,19 @@ module AbAdmin
187
199
  AbAdmin.site_name.is_a?(String) ? AbAdmin.site_name : AbAdmin.site_name.call
188
200
  end
189
201
 
190
- def call_method_or_proc_on(obj, symbol_or_proc, options = {})
191
- exec = options[:exec].nil? ? true : options[:exec]
192
- case symbol_or_proc
193
- when String
194
- ActiveSupport::Deprecation.warn('`call_method_or_proc_on` don\'t accept method name as String, use Symbol instead') if symbol_or_proc =~ /\A\w+\z/
195
- symbol_or_proc
196
- when Symbol
197
- obj.send(symbol_or_proc.to_sym)
198
- when Proc
199
- exec ? instance_exec(obj, &symbol_or_proc) : symbol_or_proc.call(obj)
202
+ def option_conditions_met?(options, object=nil)
203
+ return true unless options
204
+ condition = options[:if] || options[:unless]
205
+ return true unless condition
206
+ options[:if] ? method_or_proc_on(condition, object) : !method_or_proc_on(condition, object)
207
+ end
208
+
209
+ def method_or_proc_on(symbol_or_proc, object=nil)
210
+ return unless symbol_or_proc
211
+ if symbol_or_proc.is_a?(Symbol)
212
+ (object || self).public_send(symbol_or_proc)
213
+ else
214
+ object ? instance_exec(object, &symbol_or_proc) : instance_exec(&symbol_or_proc)
200
215
  end
201
216
  end
202
217
  end
@@ -16,7 +16,7 @@ module AbAdmin
16
16
  end
17
17
 
18
18
  def list_sort_link(attribute, options={})
19
- adapter = options[:adapter] || @search
19
+ adapter = options[:adapter] || ransack_collection
20
20
  if adapter && adapter.klass == resource_class
21
21
  sort_link(adapter, attribute, options)
22
22
  else
@@ -25,7 +25,7 @@ module AbAdmin
25
25
  end
26
26
 
27
27
  def sort_link(adapter, attribute, options={})
28
- name = options[:title] || (attribute.is_a?(Symbol) ? ha(attribute) : attribute)
28
+ name = options.delete(:title) || (attribute.is_a?(Symbol) ? ha(attribute) : attribute)
29
29
  return name unless adapter
30
30
  search_params = (params[:q] || {}).to_h.with_indifferent_access
31
31
  attr_name = (options.delete(:column) || attribute).to_s
@@ -48,7 +48,7 @@ module AbAdmin
48
48
  html_options = options.delete(:html_options) || {}
49
49
  html_options[:class] = ['sort_link', current_dir, html_options[:class]].compact.join(' ')
50
50
 
51
- options.merge!(q: search_params.merge(s: "#{attr_name} #{new_dir}"), **scope_params)
51
+ options.merge!(q: search_params.merge(s: "#{attr_name} #{new_dir}"), **collection_params)
52
52
  link_to [name, order_indicator_for(current_dir)].join(' ').html_safe, url_for(options), html_options
53
53
  end
54
54
 
@@ -62,8 +62,8 @@ module AbAdmin
62
62
  end
63
63
  end
64
64
 
65
- def scope_params
66
- params.slice(*button_scopes.map(&:first)).permit!.to_h.symbolize_keys
65
+ def collection_params
66
+ params.slice(:index_view, :view_options, *button_scopes.map(&:name)).permit!.to_h.symbolize_keys
67
67
  end
68
68
 
69
69
  def short_action_link(action, item)
@@ -80,9 +80,7 @@ module AbAdmin
80
80
  class: 'btn btn-info', title: t('admin.actions.show.link')
81
81
  when :preview
82
82
  preview_path = preview_resource_path(item)
83
- if preview_path
84
- link_to icon('eye-open', true), preview_path, class: 'btn btn-inverse', title: t('admin.actions.preview.link'), target: '_blank'
85
- end
83
+ link_to(icon('eye-open', true), preview_path, class: 'btn btn-inverse', title: t('admin.actions.preview.link'), target: '_blank') if preview_path
86
84
  when :history
87
85
  item_link_to_can? :history, item, icon('book', true), history_resource_path(item),
88
86
  class: 'btn btn-info', title: t('admin.actions.history.link')
@@ -111,9 +109,8 @@ module AbAdmin
111
109
  when :show
112
110
  link_to_can? :show, t('admin.actions.show.link'), resource_path, class: 'btn btn-info'
113
111
  when :preview
114
- if path = preview_resource_path(resource)
115
- link_to t('admin.actions.preview.link'), path, class: 'btn btn-inverse', title: t('admin.actions.preview.link'), target: '_blank'
116
- end
112
+ preview_path = preview_resource_path(resource)
113
+ link_to(t('admin.actions.preview.link'), preview_path, class: 'btn btn-inverse', title: t('admin.actions.preview.link'), target: '_blank') if preview_path
117
114
  when :history
118
115
  link_to_can? :history, t('admin.actions.history.link'), history_resource_path, class: 'btn btn-info'
119
116
  when AbAdmin::Config::ActionItem
@@ -129,8 +126,14 @@ module AbAdmin
129
126
  end
130
127
  end
131
128
 
129
+ def preview_resource_path(item)
130
+ return unless controller_name == 'manager' && manager.preview_path && option_conditions_met?(manager.preview_path[:options], item)
131
+ manager.preview_path[:value].is_a?(Symbol) ? public_send(manager.preview_path[:value], item) : instance_exec(item, &manager.preview_path[:value])
132
+ end
133
+
132
134
  def link_to_can?(act, *args, &block)
133
- item_link_to_can?(act, get_subject, *args, &block)
135
+ subject = params[:id] ? resource : resource_class
136
+ item_link_to_can?(act, subject, *args, &block)
134
137
  end
135
138
 
136
139
  def item_link_to_can?(act, item, *args, &block)
@@ -167,8 +170,7 @@ module AbAdmin
167
170
  if total_entries.zero?
168
171
  t('will_paginate.pagination_info_empty')
169
172
  else
170
- per_page = (params[:per_page] || resource_class.per_page).to_i
171
- t('will_paginate.pagination_info', from: offset + 1, to: [offset + per_page, total_entries].min, count: total_entries).html_safe
173
+ t('will_paginate.pagination_info', from: offset + 1, to: [offset + settings[:per_page], total_entries].min, count: total_entries).html_safe
172
174
  end
173
175
  end
174
176
 
@@ -192,7 +194,7 @@ module AbAdmin
192
194
  end
193
195
 
194
196
  def admin_comments_button(item)
195
- title = [icon('comment', true), item.admin_comments_count_non_zero].compact.join(' ').html_safe
197
+ title = [icon('comment', true), (item.admin_comments_count unless item.admin_comments_count.zero?)].compact.join(' ').html_safe
196
198
  link_to title, admin_admin_comments_path(resource_type: item.class.name, resource_id: item.id), remote: true,
197
199
  class: 'btn btn-info list_admin_comments_link'
198
200
  end
@@ -208,7 +210,7 @@ module AbAdmin
208
210
  def batch_action_item(item)
209
211
  if settings[:batch]
210
212
  content_tag :td do
211
- check_box_tag 'by_ids[]', item.id, false, id: "batch_action_item_#{item.id}", class: 'batch_check'
213
+ check_box_tag 'q[id_in][]', item.id, false, id: "batch_action_item_#{item.id}", class: 'batch_check'
212
214
  end
213
215
  end
214
216
  end
@@ -93,21 +93,23 @@ module AbAdmin
93
93
  return if @disable_all
94
94
  model = @object.class.reflect_on_association(assoc).klass
95
95
  title = [@template.icon('plus', true), I18n.t('admin.add'), options[:title] || model.model_name.human].join(' ').html_safe
96
- link_to_add title, assoc, class: "btn btn-primary #{options[:class]}"
96
+ options[:class] = "btn btn-primary #{options[:class]}"
97
+ link_to_add title, assoc, options
97
98
  end
98
99
 
99
- def link_to_remove_assoc
100
+ def link_to_remove_assoc(options={})
100
101
  return if @disable_all
101
- link_to_remove @template.icon('trash', true) + I18n.t('admin.delete'), class: 'btn btn-danger btn-mini pull-right'
102
+ options[:class] ||= 'btn btn-danger btn-mini pull-right'
103
+ link_to_remove @template.icon('trash', true) + I18n.t('admin.delete'), options
102
104
  end
103
105
 
104
106
  def locale_tabs(options={}, &block)
105
107
  locale_html = {}
106
- options[:locales] ||= Globalize.available_locales
108
+ options[:locales] ||= AbAdmin.translated_locales
107
109
  options[:locales].each do |l|
108
110
  locale_html[l] = template.capture { block.call(l) }
109
111
  end
110
- template.render 'admin/shared/locale_tabs', locale_html: locale_html, locales: options[:locales]
112
+ template.render 'admin/shared/locale_tabs', locale_html: locale_html, locales: options[:locales], tab_nav: options[:tab_nav]
111
113
  end
112
114
 
113
115
  def save_buttons
@@ -1,15 +1,6 @@
1
1
  module AbAdmin
2
2
  module Views
3
3
  module Helpers
4
-
5
- def admin?
6
- user_signed_in? && current_user.admin?
7
- end
8
-
9
- def moderator?
10
- user_signed_in? && current_user.moderator?
11
- end
12
-
13
4
  def as_html(text)
14
5
  return ''.html_safe if text.nil?
15
6
  Nokogiri::HTML.fragment(text).to_html.html_safe
@@ -3,11 +3,7 @@ module AbAdmin
3
3
  module Inputs
4
4
  class CkeditorInput < ::SimpleForm::Inputs::Base
5
5
  def input(wrapper_options=nil)
6
- unless @builder.template.instance_variable_get(:@ckeditor_init)
7
- @builder.template.concat @builder.template.javascript_include_tag('/javascripts/ckeditor/init')
8
- @builder.template.instance_variable_set(:@ckeditor_init, true)
9
- end
10
- input_html_options.reverse_merge!({width: 800, height: 200, toolbar: 'Easy'})
6
+ input_html_options.reverse_merge!({width: 800, height: 200, data: {cdn_url: Ckeditor.cdn_url}})
11
7
  @builder.cktext_area(attribute_name, input_html_options)
12
8
  end
13
9
  end
@@ -1,9 +1,6 @@
1
1
  module AbAdmin
2
2
  module Views
3
3
  module ManagerHelpers
4
-
5
- INDEX_VIEW_ICONS = {table: 'list', tree: 'move', grid: 'th', chart: 'signal'}
6
-
7
4
  def table_builder
8
5
  manager.table ||= ::AbAdmin::Config::Table.default_for_model(resource_class)
9
6
  end
@@ -20,6 +17,14 @@ module AbAdmin
20
17
  manager.chart ||= ::AbAdmin::Config::Chart.default_for_model(resource_class)
21
18
  end
22
19
 
20
+ def stats_builder
21
+ manager.stats ||= ::AbAdmin::Config::Stats.default_for_model(resource_class)
22
+ end
23
+
24
+ def map_builder
25
+ manager.map ||= ::AbAdmin::Config::Map.default_for_model(resource_class)
26
+ end
27
+
23
28
  def modal_form_builder
24
29
  manager.modal_form ||= ::AbAdmin::Config::ModalForm.default_for_model(resource_class, skip: [:id, :created_at, :updated_at, :lft, :rgt, :depth])
25
30
  end
@@ -38,7 +43,7 @@ module AbAdmin
38
43
  elsif field.options[:image]
39
44
  item_image_link(item, assoc: field.name)
40
45
  else
41
- admin_pretty_data call_method_or_proc_on(item, field.data)
46
+ admin_pretty_data method_or_proc_on(field.data, item)
42
47
  end
43
48
  end
44
49
 
@@ -52,10 +57,14 @@ module AbAdmin
52
57
  end
53
58
  end
54
59
 
60
+ INDEX_VIEW_ICONS = {table: 'list', tree: 'move', grid: 'th', chart: 'signal', map: 'map-marker', stats: 'eye-open'}
61
+ INDEX_VIEW_SYMBOLS = {pie_chart: '◔'}
55
62
  def index_view_link(index_view)
56
- options = {class: "btn #{('active' if current_index_view == index_view)}", title: t("admin.index_view.#{index_view}", default: index_view.to_s)}
63
+ options = {class: ['btn', 'tool', 'tool-bottom', ('active' if settings[:current_index_view] == index_view)], title: t("admin.index_view.#{index_view}", default: index_view.to_s)}
57
64
  url = url_for({index_view: index_view, q: params[:q]}.reject_blank)
58
- link_to icon(INDEX_VIEW_ICONS[index_view.to_sym]), url, options
65
+ title = INDEX_VIEW_ICONS[index_view.to_sym] ? icon(INDEX_VIEW_ICONS[index_view.to_sym]) : (INDEX_VIEW_SYMBOLS[index_view.to_sym] || index_view.to_s)
66
+ options[:class] << 'btn-symbol' if INDEX_VIEW_SYMBOLS[index_view.to_sym]
67
+ link_to title, url, options
59
68
  end
60
69
  end
61
70
  end