ab_admin 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/ab_admin/components/admin_assets.js.coffee +6 -2
- data/app/assets/javascripts/ab_admin/components/base_assets.js.coffee +9 -0
- data/app/assets/javascripts/ab_admin/components/gmaps.js.coffee +1 -1
- data/app/assets/javascripts/ab_admin/components/in_place_edit.js.coffee +6 -0
- data/app/assets/javascripts/ab_admin/components/select2_bridge.js.coffee +2 -2
- data/app/assets/javascripts/ab_admin/core/batch_actions.js.coffee +52 -12
- data/app/assets/javascripts/ab_admin/core/init.js.coffee +2 -0
- data/app/assets/javascripts/ab_admin/core/pjax.js.coffee +3 -2
- data/app/assets/javascripts/ab_admin/core/ui_utils.js.coffee +3 -4
- data/app/assets/stylesheets/ab_admin/bootstrap_and_overrides.scss +4 -0
- data/app/assets/stylesheets/ab_admin/components/_colored_tabs.scss +4 -0
- data/app/assets/stylesheets/ab_admin/components/_form.scss +36 -3
- data/app/controllers/admin/admin_comments_controller.rb +4 -0
- data/app/controllers/admin/assets_controller.rb +5 -2
- data/app/controllers/admin/base_controller.rb +50 -41
- data/app/controllers/admin/locators_controller.rb +1 -1
- data/app/controllers/admin/manager_controller.rb +32 -3
- data/app/controllers/admin/settings_controller.rb +2 -3
- data/app/controllers/admin/static_pages_controller.rb +5 -0
- data/app/controllers/admin/structures_controller.rb +10 -4
- data/app/controllers/admin/users_controller.rb +9 -2
- data/app/views/admin/base/_search_layout.html.slim +0 -1
- data/app/views/admin/base/index.html.slim +1 -2
- data/app/views/admin/fileupload/_container.html.slim +17 -10
- data/app/views/admin/shared/_content_actions.html.slim +18 -6
- data/app/views/admin/shared/_locale_tabs.html.slim +3 -3
- data/app/views/admin/structures/_form.html.slim +2 -1
- data/app/views/layouts/admin/_footer.html.slim +5 -4
- data/app/views/layouts/admin/application.html.slim +2 -0
- data/config/locales/ru.yml +1 -0
- data/config/routes.rb +17 -22
- data/lib/ab_admin.rb +11 -1
- data/lib/ab_admin/abstract_resource.rb +11 -2
- data/lib/ab_admin/carrierwave/base_uploader.rb +45 -25
- data/lib/ab_admin/carrierwave/file_size_validator.rb +0 -1
- data/lib/ab_admin/carrierwave/glue.rb +2 -4
- data/lib/ab_admin/concerns/admin_addition.rb +12 -4
- data/lib/ab_admin/concerns/deep_cloneable.rb +0 -1
- data/lib/ab_admin/concerns/fileuploads.rb +0 -1
- data/lib/ab_admin/concerns/headerable.rb +0 -4
- data/lib/ab_admin/concerns/nested_set.rb +2 -3
- data/lib/ab_admin/concerns/reloadable.rb +0 -2
- data/lib/ab_admin/concerns/silencer.rb +0 -3
- data/lib/ab_admin/concerns/utilities.rb +2 -4
- data/lib/ab_admin/concerns/validations.rb +1 -1
- data/lib/ab_admin/config/base.rb +26 -6
- data/lib/ab_admin/controllers/callbacks.rb +6 -6
- data/lib/ab_admin/controllers/head_options.rb +0 -1
- data/lib/ab_admin/controllers/tree.rb +0 -2
- data/lib/ab_admin/core_ext.rb +1 -1
- data/lib/ab_admin/core_ext/array.rb +0 -1
- data/lib/ab_admin/core_ext/hash.rb +11 -0
- data/lib/ab_admin/core_ext/string.rb +0 -1
- data/lib/ab_admin/devise.rb +1 -1
- data/lib/ab_admin/engine.rb +2 -1
- data/lib/ab_admin/hooks/globalize_locale_suffix_accessors.rb +17 -31
- data/lib/ab_admin/hooks/will_paginate_no_uri.rb +1 -1
- data/lib/ab_admin/i18n_tools/google_translate.rb +0 -1
- data/lib/ab_admin/i18n_tools/translate_app.rb +0 -1
- data/lib/ab_admin/menu/builder.rb +3 -2
- data/lib/ab_admin/menu/group.rb +3 -1
- data/lib/ab_admin/models/asset.rb +9 -6
- data/lib/ab_admin/models/header.rb +2 -3
- data/lib/ab_admin/models/locator.rb +1 -1
- data/lib/ab_admin/models/settings.rb +6 -6
- data/lib/ab_admin/models/structure.rb +0 -6
- data/lib/ab_admin/models/track.rb +12 -3
- data/lib/ab_admin/models/type_model.rb +0 -1
- data/lib/ab_admin/models/user.rb +0 -1
- data/lib/ab_admin/models/validations/all.rb +4 -0
- data/lib/ab_admin/models/validations/domain_name_validator.rb +9 -0
- data/lib/ab_admin/models/validations/email_validator.rb +9 -0
- data/lib/ab_admin/utils.rb +12 -4
- data/lib/ab_admin/utils/eval_helpers.rb +1 -1
- data/lib/ab_admin/utils/logger.rb +0 -2
- data/lib/ab_admin/utils/xls_document.rb +25 -6
- data/lib/ab_admin/version.rb +1 -1
- data/lib/ab_admin/views/admin_helpers.rb +5 -4
- data/lib/ab_admin/views/admin_navigation_helpers.rb +16 -5
- data/lib/ab_admin/views/form_builder.rb +41 -10
- data/lib/ab_admin/views/helpers.rb +0 -2
- data/lib/ab_admin/views/inputs/uploader_input.rb +1 -0
- data/lib/ab_admin/views/search_form_builder.rb +33 -7
- data/lib/generators/ab_admin/ckeditor_assets/ckeditor_assets_generator.rb +0 -1
- data/lib/generators/ab_admin/glob/glob_generator.rb +2 -2
- data/lib/generators/ab_admin/glob/templates/migration.erb +1 -1
- data/lib/generators/ab_admin/install/install_generator.rb +0 -1
- data/lib/generators/ab_admin/install/templates/config/seeds.rb +0 -2
- data/lib/generators/ab_admin/install/templates/helpers/admin/structures_helper.rb +1 -4
- data/lib/generators/ab_admin/install/templates/models/admin_comment.rb +1 -3
- data/lib/generators/ab_admin/install/templates/models/asset.rb +3 -5
- data/lib/generators/ab_admin/install/templates/models/header.rb +1 -5
- data/lib/generators/ab_admin/install/templates/models/static_page.rb +1 -4
- data/lib/generators/ab_admin/install/templates/models/structure.rb +1 -5
- data/lib/generators/ab_admin/install/templates/models/track.rb +1 -2
- data/lib/generators/ab_admin/install/templates/models/user.rb +1 -9
- data/lib/generators/ab_admin/install/templates/uploaders/attachment_file_uploader.rb +1 -1
- data/lib/generators/ab_admin/install/templates/uploaders/avatar_uploader.rb +1 -1
- data/lib/generators/ab_admin/install/templates/uploaders/picture_uploader.rb +1 -1
- data/lib/generators/ab_admin/model/templates/resource.erb +1 -0
- data/lib/generators/template.rb +39 -59
- metadata +38 -36
- data/lib/ab_admin/hooks/active_model_attr_accessible_few_roles.rb +0 -50
@@ -9,7 +9,7 @@ class ::Admin::LocatorsController < ::Admin::BaseController
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def update
|
12
|
-
if Locator.save(@file, {params[:edit_locale_name] => params
|
12
|
+
if Locator.save(@file, {params[:edit_locale_name] => params.require(:locale_hash).permit!.to_h})
|
13
13
|
flash[:notice] = I18n.t('flash.admin.locators.updated')
|
14
14
|
redirect_to admin_locators_path
|
15
15
|
else
|
@@ -18,6 +18,14 @@ class ::Admin::ManagerController < ::Admin::BaseController
|
|
18
18
|
|
19
19
|
protected
|
20
20
|
|
21
|
+
def button_scopes
|
22
|
+
manager.scopes.map{|scope| [scope.name, scope.options] }
|
23
|
+
end
|
24
|
+
|
25
|
+
def with_scopes(relation)
|
26
|
+
manager.scopes.inject(relation) { |result, scope| scope.apply(result, params) }
|
27
|
+
end
|
28
|
+
|
21
29
|
def begin_of_association_chain
|
22
30
|
parent
|
23
31
|
end
|
@@ -68,8 +76,9 @@ class ::Admin::ManagerController < ::Admin::BaseController
|
|
68
76
|
manager.default_action_items_for(action_name.to_sym, for_resource) + manager.action_items_for(action_name.to_sym)
|
69
77
|
end
|
70
78
|
|
71
|
-
def apply_batch_action(item, batch_action)
|
72
|
-
|
79
|
+
def apply_batch_action(item, batch_action, *batch_params)
|
80
|
+
data = manager.batch_action_list.detect{|a| a.name == batch_action }.data
|
81
|
+
success = call_method_or_proc_on item, data, exec: false, attrs: batch_params
|
73
82
|
track_action!("batch_#{batch_action}", item) if settings[:history]
|
74
83
|
success
|
75
84
|
end
|
@@ -115,9 +124,29 @@ class ::Admin::ManagerController < ::Admin::BaseController
|
|
115
124
|
end
|
116
125
|
end
|
117
126
|
|
127
|
+
def permitted_params
|
128
|
+
attrs = case manager.permitted_params
|
129
|
+
when Proc then
|
130
|
+
instance_exec(&manager.permitted_params)
|
131
|
+
else
|
132
|
+
Array(manager.permitted_params)
|
133
|
+
end
|
134
|
+
|
135
|
+
resource_params = params[resource_class.model_name.param_key]
|
136
|
+
return {} unless resource_params
|
137
|
+
if attrs.first == :all
|
138
|
+
resource_params.permit!
|
139
|
+
else
|
140
|
+
attrs = attrs + AbAdmin.default_permitted_params
|
141
|
+
resource_params.permit(*attrs)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
118
145
|
def preview_resource_path(item)
|
119
146
|
return unless manager.preview_path
|
120
|
-
|
147
|
+
I18n.with_locale I18n.default_locale do
|
148
|
+
manager.preview_path.is_a?(Proc) ? instance_exec(item, &manager.preview_path) : send(manager.preview_path, item)
|
149
|
+
end
|
121
150
|
end
|
122
151
|
|
123
152
|
def admin_partial_name(builder)
|
@@ -4,9 +4,9 @@ class ::Admin::SettingsController < ::Admin::BaseController
|
|
4
4
|
defaults resource_class: Settings
|
5
5
|
|
6
6
|
def update
|
7
|
-
Settings.instance.save(params
|
7
|
+
Settings.instance.save(params.require(:settings).permit!.to_h)
|
8
8
|
Settings.reload_checker.expire
|
9
|
-
|
9
|
+
redirect_back fallback_location: admin_root_url
|
10
10
|
end
|
11
11
|
|
12
12
|
def cache_clear
|
@@ -31,5 +31,4 @@ class ::Admin::SettingsController < ::Admin::BaseController
|
|
31
31
|
def resource
|
32
32
|
Settings.instance
|
33
33
|
end
|
34
|
-
|
35
34
|
end
|
@@ -11,4 +11,9 @@ class Admin::StaticPagesController < Admin::BaseController
|
|
11
11
|
{}
|
12
12
|
end
|
13
13
|
|
14
|
+
def permitted_params
|
15
|
+
attrs = [:structure_id, :title, :content, :kind, :is_visible,
|
16
|
+
*StaticPage.all_translated_attribute_names, *AbAdmin.default_permitted_params]
|
17
|
+
params[:static_page].try!(:permit, *attrs)
|
18
|
+
end
|
14
19
|
end
|
@@ -3,15 +3,12 @@ class Admin::StructuresController < Admin::BaseController
|
|
3
3
|
|
4
4
|
load_and_authorize_resource
|
5
5
|
|
6
|
-
#has_scope :visible
|
7
|
-
#has_scope :un_visible
|
8
|
-
|
9
6
|
protected
|
10
7
|
|
11
8
|
def resource_action_items
|
12
9
|
edit_structure = AbAdmin::Config::ActionItem.new({}) { |r| link_to icon('wrench', true), edit_resource_path(r), class: 'btn btn-warning' }
|
13
10
|
edit_static_page = AbAdmin::Config::ActionItem.new({}) do |r|
|
14
|
-
link_to(icon('pencil', true), edit_structure_record_path(r), class: 'btn btn-primary') if r.structure_type.static_page?
|
11
|
+
link_to(icon('pencil', true), edit_structure_record_path(r), class: 'btn btn-primary') if r.structure_type.static_page? || r.structure_type.main?
|
15
12
|
end
|
16
13
|
[edit_static_page, edit_structure, :destroy, :show]
|
17
14
|
end
|
@@ -23,4 +20,13 @@ class Admin::StructuresController < Admin::BaseController
|
|
23
20
|
def settings
|
24
21
|
{index_view: 'tree', default_order: 'lft'}
|
25
22
|
end
|
23
|
+
|
24
|
+
def permitted_params
|
25
|
+
attrs = [:structure_type_id, :position_type_id, :parent_id, :title, :redirect_url, :is_visible,
|
26
|
+
:structure_type, :position_type,
|
27
|
+
*Structure.simple_slug_columns,
|
28
|
+
*AbAdmin.default_permitted_params,
|
29
|
+
*Structure.all_translated_attribute_names, header_attributes: [:id, *Header.all_translated_attribute_names]]
|
30
|
+
params[:structure].try!(:permit, *attrs)
|
31
|
+
end
|
26
32
|
end
|
@@ -3,12 +3,12 @@ class Admin::UsersController < Admin::BaseController
|
|
3
3
|
|
4
4
|
def activate
|
5
5
|
resource.activate!
|
6
|
-
|
6
|
+
redirect_back fallback_location: admin_users_url
|
7
7
|
end
|
8
8
|
|
9
9
|
def suspend
|
10
10
|
resource.suspend!
|
11
|
-
|
11
|
+
redirect_back fallback_location: admin_users_url
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
@@ -46,4 +46,11 @@ class Admin::UsersController < Admin::BaseController
|
|
46
46
|
resource
|
47
47
|
end
|
48
48
|
|
49
|
+
def permitted_params
|
50
|
+
attrs = [:password, :password_confirmation, :email, :remember_me,
|
51
|
+
:login, :first_name, :last_name, :patronymic, :phone, :skype, :web_site, :address, :birthday,
|
52
|
+
:time_zone, :locale, :bg_color, :gender, *AbAdmin.default_permitted_params]
|
53
|
+
attrs << [:user_role_id] if admin?
|
54
|
+
params[:user].try!(:permit, *attrs)
|
55
|
+
end
|
49
56
|
end
|
@@ -10,8 +10,7 @@
|
|
10
10
|
.btn-toolbar.pull-right.pjax_links
|
11
11
|
.btn-group
|
12
12
|
- per_page_variants.each do |c|
|
13
|
-
a.btn.per_page data-val=c href=url_for(
|
13
|
+
a.btn.per_page data-val=c href=url_for(params_for_links.merge(per_page: c)) class=('active' if c == collection.per_page) = c
|
14
14
|
|
15
15
|
- if pjax? && flash.present?
|
16
16
|
script type='text/javascript' = render partial: 'admin/shared/flash', formats: :js, local_assigns: {flash: flash}
|
17
|
-
|
@@ -1,15 +1,22 @@
|
|
1
1
|
.fileupload id=options[:container_id] class=options[:container_class]
|
2
2
|
= options[:error]
|
3
3
|
.fileupload-list.clearfix= render partial: asset_template, collection: assets
|
4
|
-
|
5
|
-
.fileupload-
|
6
|
-
.
|
7
|
-
|
8
|
-
|
4
|
+
- unless options[:disabled]
|
5
|
+
.fileupload-upload
|
6
|
+
.fileupload-button.pull-left
|
7
|
+
.btn= options[:button_title] || I18n.t("admin.fileupload.button#{'s' if options[:multiple]}")
|
8
|
+
= file_field_tag 'data', multiple: options[:multiple]
|
9
|
+
.fileupload-edit-button.btn.pull-left= t('admin.actions.edit.link')
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
.fileupload-info
|
12
|
+
- if options[:extensions]
|
13
|
+
.fileupload-info-extensions= options[:extensions].join(', ')
|
14
|
+
.fileupload-info-max_size== "#{t('admin.fileupload.max_size')}: <b>#{options[:max_size]}</b> MB"
|
14
15
|
|
15
|
-
|
16
|
+
javascript:
|
17
|
+
if (document.readyState == 'complete') {
|
18
|
+
new AdminAssets(#{{js_options.to_json}});
|
19
|
+
}
|
20
|
+
else {
|
21
|
+
$(function(){new AdminAssets(#{{js_options.to_json}});});
|
22
|
+
}
|
@@ -7,12 +7,24 @@
|
|
7
7
|
ul.dropdown-menu
|
8
8
|
- batch_action_list.each do |batch_action|
|
9
9
|
li
|
10
|
-
a.batch_action_link
|
10
|
+
a.batch_action_link(
|
11
|
+
href='#'
|
12
|
+
data-form=batch_action.form
|
13
|
+
data-action=batch_action.name
|
14
|
+
data-confirm=batch_action.confirm
|
15
|
+
)
|
16
|
+
= batch_action.title
|
11
17
|
- unless button_scopes.blank?
|
12
18
|
.btn-group.pjax_links
|
13
19
|
- button_scopes.each do |name, opts|
|
14
|
-
-
|
15
|
-
|
20
|
+
- param_name = opts[:as] || name
|
21
|
+
- active = params[param_name]
|
22
|
+
a.btn href=url_for(param_name => (active ? nil : 1)) class=('active' if active)
|
23
|
+
= t "admin.scopes.#{name}", default: name.to_s.titleize
|
24
|
+
- if opts[:badge]
|
25
|
+
- scope_count = resource_class.send(name).count
|
26
|
+
- unless scope_count.zero?
|
27
|
+
span.badge< class=("badge-#{opts[:badge][:type] || 'important'}") = scope_count
|
16
28
|
|
17
29
|
a.btn.pull-left#columns_hider_show href="#columns_hider" data-toggle='modal' = t 'admin.columns_hider.button'
|
18
30
|
|
@@ -29,9 +41,9 @@
|
|
29
41
|
.btn-group.downloads
|
30
42
|
= icon('download-alt')
|
31
43
|
/- %w(csv xls json).each do |format|
|
32
|
-
- %w(csv
|
33
|
-
- next if format == '
|
34
|
-
= link_to format,
|
44
|
+
- %w(csv xlsx).each do |format|
|
45
|
+
- next if format == 'xlsx' && !Mime[:xlsx]
|
46
|
+
= link_to format, params_for_links.merge(per_page: 10_000, format: format), id: "export_#{format}"
|
35
47
|
|
36
48
|
- if @search && settings[:sort_buttons]
|
37
49
|
.btn-group
|
@@ -1,8 +1,8 @@
|
|
1
1
|
.tabbable.locale_tabs
|
2
2
|
ul.nav.nav-tabs
|
3
|
-
-
|
3
|
+
- locales.each_with_index do |l, i|
|
4
4
|
li class=('active' if i.zero?)
|
5
5
|
a data-toggle="tab" href="##{l}" class="ico_#{l}" = t("admin.langs.#{l}", default: l.to_s)
|
6
6
|
.tab-content
|
7
|
-
-
|
8
|
-
.tab-pane id=l class="tab_#{l} #{'active' if i.zero?}" =
|
7
|
+
- locales.each_with_index do |l, i|
|
8
|
+
.tab-pane id=l class="tab_#{l} #{'active' if i.zero?}" = locale_html[l]
|
@@ -3,7 +3,8 @@
|
|
3
3
|
= f.input :title, locale: l
|
4
4
|
= f.input :redirect_url, locale: l, as: :string
|
5
5
|
|
6
|
-
|
6
|
+
- Structure.simple_slug_columns.each do |column|
|
7
|
+
= f.input column
|
7
8
|
- if @structure.moveable?
|
8
9
|
= f.input :parent, as: :tree_select
|
9
10
|
= f.input :structure_type_id, collection: StructureType.all
|
@@ -1,7 +1,8 @@
|
|
1
|
-
footer
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
- if AbAdmin.footer
|
2
|
+
footer
|
3
|
+
' Powered by
|
4
|
+
a href='https://github.com/leschenko/ab_admin' target='_blank' = "AbAdmin #{AbAdmin::VERSION}"
|
5
|
+
.muted.footer-notes= AbAdmin.footer_notes
|
5
6
|
|
6
7
|
= cache [I18n.locale, 'admin', 'footer'] do
|
7
8
|
= render 'admin/fileupload/asset_templates'
|
@@ -8,6 +8,8 @@ html id="controller_#{controller_name}"
|
|
8
8
|
= include_fv
|
9
9
|
= javascript_include_tag 'ab_admin/application'
|
10
10
|
= csrf_meta_tags
|
11
|
+
- if AbAdmin.favicon_path
|
12
|
+
link rel="icon" type="image/x-icon" href=AbAdmin.favicon_path
|
11
13
|
= yield(:head)
|
12
14
|
body id="action_#{action_name}" class="resource_#{resource_collection_name} #{AbAdmin.body_css_class}"
|
13
15
|
#wrap
|
data/config/locales/ru.yml
CHANGED
data/config/routes.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
|
-
|
3
2
|
namespace :admin do
|
4
|
-
root to: 'dashboards#index'
|
3
|
+
root to: 'dashboards#index', as: :root
|
5
4
|
get 'dashboards', as: 'dashboards'
|
6
5
|
|
7
6
|
resources :structures do
|
@@ -33,27 +32,23 @@ Rails.application.routes.draw do
|
|
33
32
|
|
34
33
|
post 'translate' => AbAdmin::I18nTools::TranslateApp
|
35
34
|
|
36
|
-
controller 'manager', constraints: {format: /(html|js|json|xml|csv|xls|xlsx)/} do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
delete '/', action: :destroy, as: 'destroy'
|
50
|
-
end
|
51
|
-
|
52
|
-
get '/', action: :index, as: 'index'
|
53
|
-
post '/', action: :create, as: 'create'
|
35
|
+
scope '(/:parent_resource/:parent_resource_id)/:model_name', controller: 'manager', constraints: {format: /(html|js|json|xml|csv|xls|xlsx)/} do
|
36
|
+
get '/new', action: :new, as: 'new'
|
37
|
+
post '/batch', action: :batch, as: 'batch'
|
38
|
+
post '/rebuild', action: :rebuild, as: 'rebuild'
|
39
|
+
match '/custom_action', action: :custom_action, as: 'collection_action', via: :all
|
40
|
+
|
41
|
+
scope ':id' do
|
42
|
+
get '/edit', action: :edit, as: 'edit'
|
43
|
+
get '/history', action: :history, as: 'history'
|
44
|
+
match '/custom_action', action: :custom_action, as: 'member_action', via: :all
|
45
|
+
get '/', action: :show, as: 'show'
|
46
|
+
patch '/', action: :update, as: 'update'
|
47
|
+
delete '/', action: :destroy, as: 'destroy'
|
54
48
|
end
|
55
|
-
end
|
56
49
|
|
50
|
+
get '/', action: :index, as: 'index'
|
51
|
+
post '/', action: :create, as: 'create'
|
52
|
+
end
|
57
53
|
end
|
58
|
-
|
59
54
|
end
|
data/lib/ab_admin.rb
CHANGED
@@ -8,6 +8,9 @@ require 'ab_admin/core_ext'
|
|
8
8
|
require 'ab_admin/engine'
|
9
9
|
|
10
10
|
module AbAdmin
|
11
|
+
DOMAINNAME_REGEXP = /\A(?:[0-9a-z]\.|[0-9a-z][0-9a-z\-]*[0-9a-z]+\.)+[a-z]{2,6}\z/
|
12
|
+
EMAIL_REGEXP = /\A[_A-Za-z0-9\-\+]+(?:\.[_A-Za-z0-9\-\+]+)*@(?:[0-9a-z]\.|[0-9a-z][0-9a-z\-]*[0-9a-z]+\.)+[a-z]{2,6}\z/
|
13
|
+
|
11
14
|
autoload :Utils, 'ab_admin/utils'
|
12
15
|
autoload :Devise, 'ab_admin/devise'
|
13
16
|
autoload :AbstractResource, 'ab_admin/abstract_resource'
|
@@ -134,6 +137,8 @@ module AbAdmin
|
|
134
137
|
|
135
138
|
mattr_accessor :body_css_class
|
136
139
|
|
140
|
+
mattr_accessor :favicon_path
|
141
|
+
|
137
142
|
mattr_accessor :devise_layout
|
138
143
|
@@devise_layout = 'admin/devise'
|
139
144
|
|
@@ -152,6 +157,9 @@ module AbAdmin
|
|
152
157
|
mattr_accessor :test_settings
|
153
158
|
@@test_settings = {}
|
154
159
|
|
160
|
+
mattr_accessor :footer
|
161
|
+
@@footer = true
|
162
|
+
|
155
163
|
mattr_accessor :footer_notes
|
156
164
|
|
157
165
|
mattr_accessor :default_url_options
|
@@ -179,12 +187,14 @@ module AbAdmin
|
|
179
187
|
mattr_accessor :per_page_variants
|
180
188
|
@@per_page_variants = [50, 100, 500, 1000]
|
181
189
|
|
190
|
+
mattr_accessor :default_permitted_params
|
191
|
+
@@default_permitted_params = [:fileupload_guid]
|
192
|
+
|
182
193
|
extend Utils
|
183
194
|
|
184
195
|
def self.setup
|
185
196
|
yield self
|
186
197
|
end
|
187
|
-
|
188
198
|
end
|
189
199
|
|
190
200
|
|
@@ -8,7 +8,7 @@ module AbAdmin
|
|
8
8
|
|
9
9
|
attr_accessor :model, :table, :search, :export, :form, :modal_form, :show, :preview_path, :actions, :custom_settings,
|
10
10
|
:batch_action_list, :action_items, :disabled_action_items, :resource_action_items, :tree_node_renderer,
|
11
|
-
:parent_resources, :custom_actions
|
11
|
+
:parent_resources, :custom_actions, :permitted_params, :scopes
|
12
12
|
|
13
13
|
def initialize
|
14
14
|
@actions = ACTIONS
|
@@ -20,6 +20,7 @@ module AbAdmin
|
|
20
20
|
@action_items_for = {}
|
21
21
|
@parent_resources = []
|
22
22
|
@custom_actions = []
|
23
|
+
@scopes = []
|
23
24
|
@model = self.class.name.sub('AbAdmin', '').safe_constantize
|
24
25
|
add_admin_addition_to_model
|
25
26
|
end
|
@@ -58,6 +59,10 @@ module AbAdmin
|
|
58
59
|
instance.preview_path = block_given? ? block : value
|
59
60
|
end
|
60
61
|
|
62
|
+
def permitted_params(*values, &block)
|
63
|
+
instance.permitted_params = block_given? ? block : values
|
64
|
+
end
|
65
|
+
|
61
66
|
def actions(*actions_to_keep)
|
62
67
|
instance.actions = begin
|
63
68
|
options = actions_to_keep.extract_options!
|
@@ -123,6 +128,10 @@ module AbAdmin
|
|
123
128
|
def collection_action(name, options={}, &block)
|
124
129
|
instance.custom_actions << AbAdmin::Config::CustomAction.new(name, options.merge(collection: true), &block)
|
125
130
|
end
|
131
|
+
|
132
|
+
def scope(name, options={}, &block)
|
133
|
+
instance.scopes << AbAdmin::Config::Scope.new(name, options, &block)
|
134
|
+
end
|
126
135
|
end
|
127
136
|
|
128
137
|
def export
|
@@ -164,4 +173,4 @@ module AbAdmin
|
|
164
173
|
model.included_modules.include?(module_constant)
|
165
174
|
end
|
166
175
|
end
|
167
|
-
end
|
176
|
+
end
|
@@ -1,18 +1,16 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'mime/types'
|
3
2
|
require 'mini_magick'
|
4
3
|
require 'carrierwave/processing/mini_magick'
|
5
|
-
require 'carrierwave/processing/mime_types'
|
6
4
|
|
7
5
|
module AbAdmin
|
8
6
|
module CarrierWave
|
9
7
|
class BaseUploader < ::CarrierWave::Uploader::Base
|
10
8
|
include ::CarrierWave::MiniMagick
|
11
|
-
include ::CarrierWave::MimeTypes
|
12
9
|
include AbAdmin::Utils::EvalHelpers
|
13
10
|
|
14
|
-
class_attribute :transliterate
|
11
|
+
class_attribute :transliterate, :human_filenames
|
15
12
|
self.transliterate = true
|
13
|
+
self.human_filenames = true
|
16
14
|
|
17
15
|
attr_accessor :internal_identifier
|
18
16
|
|
@@ -20,8 +18,6 @@ module AbAdmin
|
|
20
18
|
|
21
19
|
storage :file
|
22
20
|
|
23
|
-
process :set_content_type
|
24
|
-
|
25
21
|
with_options if: :image? do |img|
|
26
22
|
img.process :strip
|
27
23
|
img.process cropper: lambda { |model| model.cropper_geometry }
|
@@ -30,19 +26,35 @@ module AbAdmin
|
|
30
26
|
|
31
27
|
process :set_model_info
|
32
28
|
|
29
|
+
def strict_filename(for_file=filename)
|
30
|
+
"#{version_name || secure_token}#{File.extname(for_file).downcase}"
|
31
|
+
end
|
32
|
+
|
33
33
|
def save_original_name(file)
|
34
34
|
model.original_name ||= file.original_filename if file.respond_to?(:original_filename)
|
35
35
|
end
|
36
36
|
|
37
|
+
def base_filename_part
|
38
|
+
if version_name
|
39
|
+
version_name.to_s.start_with?('retina_') ? "#{version_name.to_s.sub(/^retina_/, '')}@2x" : version_name.to_s
|
40
|
+
else
|
41
|
+
secure_token
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
37
45
|
def full_filename(for_file=filename)
|
38
|
-
|
46
|
+
human_filenames ? human_full_filename(for_file) : strict_filename(for_file)
|
47
|
+
end
|
48
|
+
|
49
|
+
def human_full_filename(for_file=filename)
|
50
|
+
ext = File.extname(for_file).downcase
|
39
51
|
human_filename_part = for_file.chomp(ext)
|
40
|
-
tech_filename_part = "#{
|
52
|
+
tech_filename_part = "#{base_filename_part}#{ext}"
|
41
53
|
human_filename_part == secure_token ? tech_filename_part : "#{human_filename_part}_#{tech_filename_part}"
|
42
54
|
end
|
43
55
|
|
44
56
|
def full_original_filename
|
45
|
-
"#{
|
57
|
+
"#{base_filename_part}#{File.extname(store_filename)}"
|
46
58
|
end
|
47
59
|
|
48
60
|
# use secure token in the filename for non processed image
|
@@ -60,7 +72,7 @@ module AbAdmin
|
|
60
72
|
alias_method :store_filename, :filename
|
61
73
|
|
62
74
|
def filename
|
63
|
-
internal_identifier || model.send("#{mounted_as}_file_name") || (store_filename && "#{secure_token}#{File.extname(store_filename)}")
|
75
|
+
internal_identifier || model.send("#{mounted_as}_file_name") || (store_filename && "#{secure_token}#{File.extname(store_filename).downcase}")
|
64
76
|
end
|
65
77
|
|
66
78
|
def write_internal_identifier(internal_identifier)
|
@@ -73,34 +85,42 @@ module AbAdmin
|
|
73
85
|
def model_filename(base_filename, record)
|
74
86
|
custom_file_name = model.build_filename(base_filename, record)
|
75
87
|
return unless custom_file_name
|
76
|
-
normalize_filename(custom_file_name) + File.extname(base_filename)
|
88
|
+
normalize_filename(custom_file_name) + File.extname(base_filename).downcase
|
77
89
|
end
|
78
90
|
|
79
91
|
def normalize_filename(raw_filename)
|
80
|
-
|
92
|
+
parameterize_args = ActiveSupport::VERSION::MAJOR > 4 ? {separator: '_'} : '_'
|
93
|
+
I18n.transliterate(raw_filename).parameterize(parameterize_args).gsub(/[\-_]+/, '_').downcase
|
81
94
|
end
|
82
95
|
|
83
96
|
# rename files via move
|
84
97
|
def rename_via_move(new_file_name)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
98
|
+
if human_filenames
|
99
|
+
dir = File.dirname(path)
|
100
|
+
|
101
|
+
moves = []
|
102
|
+
versions.values.unshift(self).each do |v|
|
103
|
+
from_path = File.join(dir, v.full_filename)
|
104
|
+
to_path = File.join(dir, v.full_filename(new_file_name))
|
105
|
+
next if from_path == to_path || !File.exists?(from_path)
|
106
|
+
moves << [from_path, to_path]
|
107
|
+
end
|
108
|
+
moves.each { |move| FileUtils.mv(*move) }
|
93
109
|
end
|
94
|
-
moves.each { |move| FileUtils.mv(*move) }
|
95
110
|
|
96
111
|
write_internal_identifier new_file_name
|
97
112
|
model.send("write_#{mounted_as}_identifier")
|
98
|
-
retrieve_from_store!(new_file_name)
|
113
|
+
retrieve_from_store!(new_file_name) if human_filenames
|
114
|
+
|
99
115
|
new_file_name
|
100
116
|
end
|
101
117
|
|
102
118
|
private :write_internal_identifier, :store_filename, :model_filename
|
103
119
|
|
120
|
+
def rmagick_included?
|
121
|
+
self.class.included_modules.map(&:to_s).include?('CarrierWave::RMagick')
|
122
|
+
end
|
123
|
+
|
104
124
|
# prevent large number of subdirectories
|
105
125
|
def store_dir
|
106
126
|
str_id = model.id.to_s.rjust(4, '0')
|
@@ -126,7 +146,7 @@ module AbAdmin
|
|
126
146
|
|
127
147
|
unless percentage.blank?
|
128
148
|
manipulate! do |img|
|
129
|
-
img.quality
|
149
|
+
img.quality percentage.to_s
|
130
150
|
img = yield(img) if block_given?
|
131
151
|
img
|
132
152
|
end
|
@@ -141,7 +161,7 @@ module AbAdmin
|
|
141
161
|
|
142
162
|
unless degrees.blank?
|
143
163
|
manipulate! do |img|
|
144
|
-
img.rotate(degrees.to_s)
|
164
|
+
rmagick_included? ? img.rotate!(degrees.to_i) : img.rotate(degrees.to_s)
|
145
165
|
img = yield(img) if block_given?
|
146
166
|
img
|
147
167
|
end
|
@@ -179,7 +199,7 @@ module AbAdmin
|
|
179
199
|
end
|
180
200
|
|
181
201
|
def image?(new_file = nil)
|
182
|
-
(file || new_file).content_type
|
202
|
+
AbAdmin.image_types.include?((file || new_file).content_type)
|
183
203
|
end
|
184
204
|
|
185
205
|
def dimensions
|