ab_admin 0.9.0 → 0.11.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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/ab_admin/components/in_place_edit.js.coffee +28 -24
- data/app/assets/javascripts/ab_admin/core/batch_actions.js.coffee +1 -1
- data/app/assets/javascripts/ab_admin/core/init.js.coffee +1 -0
- data/app/assets/javascripts/ab_admin/core/ui_utils.js.coffee +21 -1
- data/app/assets/javascripts/ab_admin/core/utils.js.coffee +8 -0
- data/app/assets/javascripts/ab_admin/inputs/datetime_input.js.coffee +1 -0
- data/app/assets/javascripts/ab_admin/main.js +1 -2
- data/app/assets/stylesheets/ab_admin/bootstrap_and_overrides.scss +44 -23
- data/app/assets/stylesheets/ab_admin/components/_colored_tabs.scss +1 -1
- data/app/assets/stylesheets/ab_admin/components/_form.scss +3 -1
- data/app/assets/stylesheets/ab_admin/components/_navigation.scss +7 -2
- data/app/assets/stylesheets/ab_admin/components/_table_view.scss +75 -9
- data/app/assets/stylesheets/ab_admin/components/_tooltip.scss +1 -0
- data/app/assets/stylesheets/ab_admin/main.scss +1 -1
- data/app/controllers/admin/assets_controller.rb +6 -2
- data/app/controllers/admin/base_controller.rb +87 -107
- data/app/controllers/admin/manager_controller.rb +17 -47
- data/app/views/ab_admin/devise/sessions/new.html.slim +2 -0
- data/app/views/admin/assets/batch_edit.html.slim +2 -1
- data/app/views/admin/base/_search_layout.html.slim +1 -1
- data/app/views/admin/base/create.js.erb +1 -1
- data/app/views/admin/base/edit.js.erb +1 -1
- data/app/views/admin/base/new.js.erb +1 -1
- data/app/views/admin/base/update.js.erb +3 -3
- data/app/views/admin/manager/_show_table.html.slim +1 -1
- data/app/views/admin/manager/_stats.html.slim +4 -0
- data/app/views/admin/manager/_table.html.slim +6 -3
- data/app/views/admin/shared/_content_actions.html.slim +22 -15
- data/app/views/admin/shared/_save_buttons.html.slim +10 -1
- data/app/views/admin/users/_form.html.slim +2 -2
- data/config/locales/en.yml +8 -13
- data/config/locales/it.yml +1 -0
- data/db/migrate/20130101000001_create_users.rb +1 -4
- data/db/migrate/20130101000003_create_assets.rb +1 -1
- data/db/migrate/20130101000004_create_headers.rb +5 -5
- data/db/migrate/20130101000005_create_static_pages.rb +2 -5
- data/db/migrate/20130101000006_create_structures.rb +1 -1
- data/db/migrate/20130101000007_base_translations.rb +43 -12
- data/db/migrate/20130101000008_create_admin_comments.rb +2 -7
- data/db/migrate/20130101000009_create_tracks.rb +4 -8
- data/lib/ab_admin/abstract_resource.rb +6 -5
- data/lib/ab_admin/carrierwave/base_uploader.rb +87 -74
- data/lib/ab_admin/carrierwave/glue.rb +0 -5
- data/lib/ab_admin/concerns/admin_addition.rb +19 -1
- data/lib/ab_admin/concerns/utilities.rb +1 -1
- data/lib/ab_admin/config/base.rb +20 -4
- data/lib/ab_admin/core_ext/array.rb +0 -5
- data/lib/ab_admin/core_ext/string.rb +1 -6
- data/lib/ab_admin/devise.rb +7 -0
- data/lib/ab_admin/engine.rb +1 -1
- data/lib/ab_admin/hooks/ckeditor_lazy.rb +13 -0
- data/lib/ab_admin/menu/base_group.rb +0 -1
- data/lib/ab_admin/menu/group.rb +2 -4
- data/lib/ab_admin/menu/item.rb +4 -8
- data/lib/ab_admin/models/asset.rb +7 -10
- data/lib/ab_admin/models/locator.rb +1 -1
- data/lib/ab_admin/models/settings.rb +2 -2
- data/lib/ab_admin/models/structure.rb +3 -3
- data/lib/ab_admin/models/track.rb +17 -5
- data/lib/ab_admin/utils/csv_document.rb +4 -4
- data/lib/ab_admin/utils/eval_helpers.rb +0 -16
- data/lib/ab_admin/utils/logger.rb +12 -2
- data/lib/ab_admin/utils/mysql.rb +2 -3
- data/lib/ab_admin/utils/xls_document.rb +1 -3
- data/lib/ab_admin/utils.rb +0 -5
- data/lib/ab_admin/version.rb +1 -1
- data/lib/ab_admin/views/admin_helpers.rb +49 -33
- data/lib/ab_admin/views/admin_navigation_helpers.rb +12 -9
- data/lib/ab_admin/views/inputs/ckeditor_input.rb +1 -5
- data/lib/ab_admin/views/manager_helpers.rb +9 -3
- data/lib/ab_admin/views/search_form_builder.rb +12 -12
- data/lib/ab_admin.rb +13 -2
- data/lib/generators/ab_admin/install/templates/models/user.rb +1 -2
- 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 +16 -3
- data/lib/generators/ab_admin/resource/resource_generator.rb +0 -4
- data/lib/generators/ab_admin/resource/templates/controller.erb +0 -7
- data/lib/tasks/assets.rake +5 -5
- metadata +24 -22
|
@@ -1,44 +1,39 @@
|
|
|
1
1
|
class Admin::BaseController < ::InheritedResources::Base
|
|
2
|
-
use Rack::Pjax, only: :index
|
|
3
|
-
|
|
4
|
-
layout :set_layout
|
|
5
|
-
|
|
6
2
|
include AbAdmin::Controllers::Fv
|
|
7
3
|
include AbAdmin::Controllers::Callbacks
|
|
8
4
|
|
|
9
|
-
|
|
5
|
+
class_attribute :export_builder, :batch_actions, :button_scopes, instance_reader: true, instance_writer: false
|
|
6
|
+
attr_reader :settings
|
|
10
7
|
|
|
11
|
-
before_action :authenticate_user!, :require_admin_access, :build_settings, :set_user_vars
|
|
8
|
+
before_action :authenticate_user!, :require_admin_access, :manager, :build_settings, :set_user_vars
|
|
12
9
|
before_action :add_breadcrumbs, :set_title, unless: :xhr?
|
|
10
|
+
before_action :preflight_batch_action, only: :batch
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
defaults finder: :friendly_find
|
|
17
|
-
|
|
18
|
-
has_scope :by_ids, type: :array
|
|
19
|
-
|
|
20
|
-
helper_method :admin?, :moderator?
|
|
21
|
-
|
|
22
|
-
attr_reader :settings
|
|
23
|
-
helper_method :button_scopes, :collection_action?, :action_items, :resource_action_items, :query_params,
|
|
24
|
-
:preview_resource_path, :get_subject, :settings, :batch_action_list, :tree_node_renderer,
|
|
12
|
+
helper_method :admin?, :moderator?, :button_scopes, :collection_action?, :action_items, :resource_action_items, :query_params,
|
|
13
|
+
:settings, :batch_actions, :tree_node_renderer,
|
|
25
14
|
:pjax?, :xhr?, :params_for_links, :resource_list_id, :ransack_collection, :search_collection
|
|
26
15
|
|
|
16
|
+
define_admin_callbacks :save, :create
|
|
17
|
+
use Rack::Pjax, only: :index
|
|
18
|
+
defaults finder: :friendly_find
|
|
27
19
|
rescue_from ::CanCan::AccessDenied, with: :render_unauthorized
|
|
20
|
+
layout :set_layout
|
|
28
21
|
|
|
29
22
|
def index
|
|
30
23
|
super do |format|
|
|
31
24
|
format.js { render layout: false }
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
doc = AbAdmin::Utils::CsvDocument.new(collection, export_options)
|
|
35
|
-
send_data(doc.render(self, locale: params[:locale]), filename: doc.filename, type: Mime[:csv], disposition: 'attachment')
|
|
36
|
-
end
|
|
37
|
-
if Mime[:xlsx]
|
|
38
|
-
format.xlsx do
|
|
25
|
+
if settings[:export]
|
|
26
|
+
format.csv do
|
|
39
27
|
authorize! :export, resource_class
|
|
40
|
-
doc = AbAdmin::Utils::
|
|
41
|
-
send_data(doc.render(self, locale: params[:locale]), filename: doc.filename, type: Mime[:
|
|
28
|
+
doc = AbAdmin::Utils::CsvDocument.new(collection, export_options)
|
|
29
|
+
send_data(doc.render(self, locale: params[:locale]), filename: doc.filename, type: Mime[:csv], disposition: 'attachment')
|
|
30
|
+
end
|
|
31
|
+
if Mime[:xlsx]
|
|
32
|
+
format.xlsx do
|
|
33
|
+
authorize! :export, resource_class
|
|
34
|
+
doc = AbAdmin::Utils::XlsDocument.new(collection, export_options)
|
|
35
|
+
send_data(doc.render(self, locale: params[:locale]), filename: doc.filename, type: Mime[:xlsx], disposition: 'attachment')
|
|
36
|
+
end
|
|
42
37
|
end
|
|
43
38
|
end
|
|
44
39
|
end
|
|
@@ -49,10 +44,15 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
49
44
|
success.html { redirect_to redirect_to_on_success }
|
|
50
45
|
success.js { render layout: false }
|
|
51
46
|
failure.js { render :new, layout: false }
|
|
47
|
+
unless respond_to_format?(:json)
|
|
48
|
+
success.json { head :no_content }
|
|
49
|
+
failure.json { render json: {errors: resource.errors}, status: :unprocessable_entity }
|
|
50
|
+
end
|
|
52
51
|
end
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
def update
|
|
55
|
+
resource.last_updated_timestamp = params[:last_updated_timestamp].to_i if settings[:safe_save] && !params[:_force_save] && params[:last_updated_timestamp]
|
|
56
56
|
update! do |success, failure|
|
|
57
57
|
success.html { redirect_to redirect_to_on_success }
|
|
58
58
|
failure.html { render :edit }
|
|
@@ -60,7 +60,7 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
60
60
|
failure.js { render :edit, layout: false }
|
|
61
61
|
unless respond_to_format?(:json)
|
|
62
62
|
success.json { head :no_content }
|
|
63
|
-
failure.json {
|
|
63
|
+
failure.json { render json: {errors: resource.errors}, status: :unprocessable_entity }
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
end
|
|
@@ -91,32 +91,26 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
def batch
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if batch_action.to_s.end_with?('_collection')
|
|
98
|
-
count = collection.size
|
|
99
|
-
resource_class.public_send(batch_action, collection, *[params[:batch_params]].compact)
|
|
100
|
-
if @settings[:history]
|
|
101
|
-
if Object.const_defined?('ActiveRecord::Import') && Track.respond_to?(:import)
|
|
102
|
-
tracks = collection.map { |item| track_action("batch_#{batch_action}", item) }
|
|
103
|
-
Track.import_from_batch_collection_action(tracks)
|
|
104
|
-
else
|
|
105
|
-
collection.each { |item| track_action!("batch_#{batch_action}", item) }
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
else
|
|
109
|
-
count = collection.inject(0) { |c, item| apply_batch_action(item, batch_action, *[params[:batch_params]].compact) ? c + 1 : c }
|
|
110
|
-
end
|
|
111
|
-
batch_action_name = I18n.t("admin.actions.batch_#{batch_action}.title", default: batch_action.to_s.humanize)
|
|
112
|
-
flash[:success] = I18n.t('admin.batch_actions.status', count: count, action: batch_action_name)
|
|
113
|
-
else
|
|
114
|
-
raise CanCan::AccessDenied
|
|
115
|
-
end
|
|
94
|
+
batch_action = batch_actions.detect{|a| a.name == params[:batch_action].to_sym }
|
|
95
|
+
count = collection.inject(0) { |c, item| apply_batch_action(item, batch_action, *params[:batch_params].presence) ? c + 1 : c }
|
|
96
|
+
flash[:success] = I18n.t('admin.batch_actions.status', count: count, action: batch_action.title)
|
|
116
97
|
redirect_to_back_or_root
|
|
117
98
|
end
|
|
118
99
|
|
|
119
|
-
|
|
100
|
+
private
|
|
101
|
+
|
|
102
|
+
def manager
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def set_layout
|
|
106
|
+
pjax? ? false : 'admin/application'
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def preflight_batch_action
|
|
110
|
+
batch_action = params[:batch_action].to_sym
|
|
111
|
+
head :unprocessable_entity unless allow_batch_action?(batch_action) && params[:q].try!(:[], :id_in).present?
|
|
112
|
+
raise CanCan::AccessDenied unless collection.all?{|item| can?(batch_action, item) }
|
|
113
|
+
end
|
|
120
114
|
|
|
121
115
|
def build_resource_params
|
|
122
116
|
permitted_params || params[resource_class.model_name.param_key]
|
|
@@ -133,22 +127,26 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
133
127
|
def default_url_options
|
|
134
128
|
options = {format: nil}
|
|
135
129
|
options.update instance_exec(&AbAdmin.default_url_options) if AbAdmin.default_url_options
|
|
136
|
-
options.update instance_exec(&@settings[:default_url_options]) if @settings[:default_url_options]
|
|
130
|
+
options.update instance_exec(&@settings[:default_url_options]) if @settings && @settings[:default_url_options]
|
|
137
131
|
options
|
|
138
132
|
end
|
|
139
133
|
|
|
134
|
+
def self.batch_action(name, options={}, &block)
|
|
135
|
+
if options
|
|
136
|
+
self.batch_actions << AbAdmin::Config::BatchAction.new(name.to_sym, options, &block)
|
|
137
|
+
else
|
|
138
|
+
self.batch_actions.reject!{|a| a.name == name.to_sym }
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
140
142
|
def apply_batch_action(item, batch_action, *batch_params)
|
|
141
|
-
success = item.
|
|
142
|
-
track_action!("batch_#{batch_action}", item) if
|
|
143
|
+
success = batch_action.data.is_a?(Symbol) ? item.public_send(batch_action.data, *batch_params) : batch_action.data.call(item)
|
|
144
|
+
track_action!("batch_#{batch_action.name}", item) if settings[:history]
|
|
143
145
|
success
|
|
144
146
|
end
|
|
145
147
|
|
|
146
148
|
def allow_batch_action?(batch_action)
|
|
147
|
-
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def redirect_to_back_or_root
|
|
151
|
-
redirect_back fallback_location: admin_root_path
|
|
149
|
+
batch_actions.detect { |a| a.name == batch_action }
|
|
152
150
|
end
|
|
153
151
|
|
|
154
152
|
def track_action(key=nil, item=nil)
|
|
@@ -159,19 +157,6 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
159
157
|
track_action(*args).save!
|
|
160
158
|
end
|
|
161
159
|
|
|
162
|
-
def batch_action_list
|
|
163
|
-
self.class.batch_action_list ||= begin
|
|
164
|
-
resource_class.batch_actions.map do |a|
|
|
165
|
-
opts = a == :destroy ? {confirm: I18n.t('admin.delete_confirmation')} : {}
|
|
166
|
-
if a.is_a?(Hash)
|
|
167
|
-
opts.merge!(a.except(:name))
|
|
168
|
-
a = a[:name]
|
|
169
|
-
end
|
|
170
|
-
AbAdmin::Config::BatchAction.new(a, opts)
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
|
|
175
160
|
def self.inherited(base)
|
|
176
161
|
super
|
|
177
162
|
base.class_eval do
|
|
@@ -179,6 +164,8 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
179
164
|
before_save :bind_current_updater
|
|
180
165
|
before_save :track_current_action
|
|
181
166
|
end
|
|
167
|
+
base.button_scopes = []
|
|
168
|
+
base.batch_actions = [AbAdmin::Config::BatchAction.new(:destroy, confirm: I18n.t('admin.delete_confirmation'))]
|
|
182
169
|
end
|
|
183
170
|
|
|
184
171
|
def track_current_action(*)
|
|
@@ -202,10 +189,6 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
202
189
|
export_builder.render_options
|
|
203
190
|
end
|
|
204
191
|
|
|
205
|
-
def preview_resource_path(item)
|
|
206
|
-
nil
|
|
207
|
-
end
|
|
208
|
-
|
|
209
192
|
def custom_settings
|
|
210
193
|
{}
|
|
211
194
|
end
|
|
@@ -219,7 +202,8 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
219
202
|
@settings[:per_page] ||= per_page
|
|
220
203
|
@settings[:per_page_variants] ||= @settings[:per_page_variants].find_all{|n| n <= @settings[:max_per_page] }
|
|
221
204
|
@settings[:sidebar] = true unless @settings.key?(:sidebar)
|
|
222
|
-
@settings[:pagination] = @settings[:pagination_index_views].include?(@settings[:current_index_view])
|
|
205
|
+
@settings[:pagination] = @settings[:pagination_index_views].include?(@settings[:current_index_view]) unless @settings.key?(:pagination)
|
|
206
|
+
@settings[:order] = active_scopes.filter_map{|sc| sc.options[:default_order] }.first || @settings[:default_order] || ('id desc' unless @settings[:current_index_view] == :tree)
|
|
223
207
|
end
|
|
224
208
|
@settings[:well] = (collection_action? || %w(show history).include?(action_name)) && @settings[:current_index_view] != :tree unless @settings.key?(:well)
|
|
225
209
|
end
|
|
@@ -243,19 +227,6 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
243
227
|
@settings[:collection_actions].include?(action_name)
|
|
244
228
|
end
|
|
245
229
|
|
|
246
|
-
def self.scope(name, options={}, &block)
|
|
247
|
-
has_scope name, options.without(:badge, :if), &block
|
|
248
|
-
options[:badge] = {} if options[:badge] && !options[:badge].is_a?(Hash)
|
|
249
|
-
options[:block] = block
|
|
250
|
-
self.button_scopes ||= []
|
|
251
|
-
self.button_scopes << [name, options]
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
def button_scopes
|
|
255
|
-
self.class.button_scopes ||= self.class.scopes_configuration.except(:by_ids).find_all{|_, s| s[:type] == :boolean }
|
|
256
|
-
self.class.button_scopes.to_h
|
|
257
|
-
end
|
|
258
|
-
|
|
259
230
|
def add_breadcrumbs
|
|
260
231
|
@breadcrumbs = []
|
|
261
232
|
if parent?
|
|
@@ -306,18 +277,28 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
306
277
|
end
|
|
307
278
|
|
|
308
279
|
def query_params
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
280
|
+
@query_params ||= begin
|
|
281
|
+
query = params[:q].try! {|q| q.permit!.to_h} || {}
|
|
282
|
+
query[:s] ||= @settings[:order]
|
|
283
|
+
query.reverse_merge!(@settings[:default_q].to_h{ [_1.to_s, _2.to_s] }) if @settings[:default_q] && !params[:q]
|
|
284
|
+
query.reject_blank
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def self.scope(name, options={}, &block)
|
|
289
|
+
self.button_scopes << ::AbAdmin::Config::Scope.new(name, options, &block)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def active_scopes
|
|
293
|
+
button_scopes.find_all{|scope| params[scope.name].present? }
|
|
313
294
|
end
|
|
314
295
|
|
|
315
296
|
def with_scopes(relation)
|
|
316
|
-
relation
|
|
297
|
+
active_scopes.inject(relation) { |result, scope| scope.apply(self, result) }
|
|
317
298
|
end
|
|
318
299
|
|
|
319
|
-
def
|
|
320
|
-
|
|
300
|
+
def redirect_to_back_or_root
|
|
301
|
+
redirect_back fallback_location: admin_root_path, turbolinks: false
|
|
321
302
|
end
|
|
322
303
|
|
|
323
304
|
def back_or_collection
|
|
@@ -382,7 +363,7 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
382
363
|
end
|
|
383
364
|
|
|
384
365
|
def require_admin_access
|
|
385
|
-
raise CanCan::AccessDenied unless current_user
|
|
366
|
+
raise CanCan::AccessDenied unless current_user&.admin_access?
|
|
386
367
|
end
|
|
387
368
|
|
|
388
369
|
def bind_current_user(*)
|
|
@@ -393,13 +374,14 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
393
374
|
resource.updater_id = current_user.id if !@settings[:skip_bind_current_updater] && resource.respond_to?(:updater_id)
|
|
394
375
|
end
|
|
395
376
|
|
|
396
|
-
def
|
|
397
|
-
|
|
377
|
+
def authenticate_user!
|
|
378
|
+
Rails.logger.debug "Redirect unauthorized user"
|
|
379
|
+
super
|
|
398
380
|
end
|
|
399
381
|
|
|
400
382
|
def render_unauthorized(exception)
|
|
401
|
-
Rails.logger.debug "Access denied on #{exception.action} #{exception.subject.inspect}, user: #{current_user
|
|
402
|
-
|
|
383
|
+
Rails.logger.debug "Access denied on #{exception.action} #{exception.subject.inspect}, user: #{current_user&.id}"
|
|
384
|
+
render_not_found and return unless AbAdmin.render_unauthorized
|
|
403
385
|
if pjax?
|
|
404
386
|
render partial: 'admin/shared/flash', locals: {flash: {alert: exception.message}}
|
|
405
387
|
elsif request.format.try(:html?)
|
|
@@ -409,11 +391,11 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
409
391
|
end
|
|
410
392
|
end
|
|
411
393
|
|
|
412
|
-
def
|
|
413
|
-
if
|
|
414
|
-
|
|
394
|
+
def render_not_found
|
|
395
|
+
if request.format.try(:html?)
|
|
396
|
+
render file: Rails.root.join('public/404.html'), layout: false, status: :not_found
|
|
415
397
|
else
|
|
416
|
-
|
|
398
|
+
head :not_found
|
|
417
399
|
end
|
|
418
400
|
end
|
|
419
401
|
|
|
@@ -421,8 +403,6 @@ class Admin::BaseController < ::InheritedResources::Base
|
|
|
421
403
|
"list_#{resource_instance_name}_#{resource.id}"
|
|
422
404
|
end
|
|
423
405
|
|
|
424
|
-
private
|
|
425
|
-
|
|
426
406
|
def per_page
|
|
427
407
|
request_per_page = (params[:per_page].presence || cookies[:pp].presence).to_i.nonzero?
|
|
428
408
|
params[:per_page] = [request_per_page || @settings[:view_default_per_page][@settings[:current_index_view]], @settings[:max_per_page]].min
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
class ::Admin::ManagerController < ::Admin::BaseController
|
|
2
|
-
include AbAdmin::Utils::EvalHelpers
|
|
3
2
|
include AbAdmin::Controllers::Tree
|
|
4
3
|
|
|
5
|
-
prepend_before_action :manager
|
|
6
|
-
|
|
7
4
|
load_and_authorize_resource
|
|
8
5
|
|
|
9
6
|
helper_method :manager, :admin_partial_name, :history_resource_path, :fetch_admin_template
|
|
@@ -11,23 +8,19 @@ class ::Admin::ManagerController < ::Admin::BaseController
|
|
|
11
8
|
def custom_action
|
|
12
9
|
custom_action = manager.custom_action_for(params[:custom_action], self)
|
|
13
10
|
if custom_action.options[:method] && custom_action.options[:method] != request.method_symbol
|
|
14
|
-
raise ActionController::RoutingError.new("AbAdmin custom action
|
|
11
|
+
raise ActionController::RoutingError.new("AbAdmin custom action #{custom_action.options[:method].to_s.upcase} #{params[:custom_action]} not allowed for #{request.method_symbol} method")
|
|
15
12
|
end
|
|
16
13
|
instance_exec(&custom_action.data)
|
|
17
14
|
end
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
private
|
|
20
17
|
|
|
21
18
|
def button_scopes
|
|
22
|
-
manager.scopes
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def with_scopes(relation)
|
|
26
|
-
scopes_to_apply.inject(relation) { |result, scope| scope.apply(result, params) }
|
|
19
|
+
manager.scopes
|
|
27
20
|
end
|
|
28
21
|
|
|
29
|
-
def
|
|
30
|
-
manager.
|
|
22
|
+
def batch_actions
|
|
23
|
+
manager.batch_actions
|
|
31
24
|
end
|
|
32
25
|
|
|
33
26
|
def begin_of_association_chain
|
|
@@ -80,21 +73,6 @@ class ::Admin::ManagerController < ::Admin::BaseController
|
|
|
80
73
|
manager.default_action_items_for(action_name.to_sym, for_resource) + manager.action_items_for(action_name.to_sym)
|
|
81
74
|
end
|
|
82
75
|
|
|
83
|
-
def apply_batch_action(item, batch_action, *batch_params)
|
|
84
|
-
data = manager.batch_action_list.detect{|a| a.name == batch_action }.data
|
|
85
|
-
success = call_method_or_proc_on item, data, exec: false, attrs: batch_params
|
|
86
|
-
track_action!("batch_#{batch_action}", item) if settings[:history]
|
|
87
|
-
success
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def allow_batch_action?(batch_action)
|
|
91
|
-
manager.batch_action_list.detect { |a| a.name == batch_action }
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def batch_action_list
|
|
95
|
-
manager.batch_action_list
|
|
96
|
-
end
|
|
97
|
-
|
|
98
76
|
def custom_settings
|
|
99
77
|
manager.custom_settings || {}
|
|
100
78
|
end
|
|
@@ -107,13 +85,11 @@ class ::Admin::ManagerController < ::Admin::BaseController
|
|
|
107
85
|
@manager ||= begin
|
|
108
86
|
manager_class_name = "AbAdmin#{resource_class.name}"
|
|
109
87
|
manager_instance = manager_class_name.constantize.instance
|
|
110
|
-
unless manager_instance.allow_action?(action_name)
|
|
111
|
-
raise ActionController::RoutingError.new("AbAdmin action #{action_name} for #{resource_class.name} not found")
|
|
112
|
-
end
|
|
88
|
+
raise ActionController::RoutingError.new("AbAdmin action #{action_name} not found") unless manager_instance.allow_action?(action_name)
|
|
113
89
|
manager_instance
|
|
114
90
|
rescue NameError => e
|
|
115
|
-
if e.message.include?(manager_class_name)
|
|
116
|
-
raise ActionController::RoutingError.new("AbAdmin
|
|
91
|
+
if e.message.include?("uninitialized constant #{manager_class_name}")
|
|
92
|
+
raise ActionController::RoutingError.new("AbAdmin manager for #{resource_class.name} not found (#{e.message})")
|
|
117
93
|
else
|
|
118
94
|
raise
|
|
119
95
|
end
|
|
@@ -122,9 +98,14 @@ class ::Admin::ManagerController < ::Admin::BaseController
|
|
|
122
98
|
|
|
123
99
|
def resource_class
|
|
124
100
|
@model ||= begin
|
|
125
|
-
params[:model_name].classify
|
|
126
|
-
|
|
127
|
-
|
|
101
|
+
model_name = params[:model_name].classify
|
|
102
|
+
model_name.constantize
|
|
103
|
+
rescue NameError => e
|
|
104
|
+
if e.message.include?("uninitialized constant #{model_name}")
|
|
105
|
+
raise ActionController::RoutingError.new("AbAdmin model #{model_name} not found (#{e.message})")
|
|
106
|
+
else
|
|
107
|
+
raise
|
|
108
|
+
end
|
|
128
109
|
end
|
|
129
110
|
end
|
|
130
111
|
|
|
@@ -140,19 +121,8 @@ class ::Admin::ManagerController < ::Admin::BaseController
|
|
|
140
121
|
end
|
|
141
122
|
end
|
|
142
123
|
|
|
143
|
-
def preview_resource_path(item)
|
|
144
|
-
return unless manager.preview_path
|
|
145
|
-
return if manager.preview_path[:options][:if] && !call_method_or_proc_on(item, manager.preview_path[:options][:if])
|
|
146
|
-
I18n.with_locale I18n.default_locale do
|
|
147
|
-
manager.preview_path[:value].is_a?(Proc) ? instance_exec(item, &manager.preview_path[:value]) : send(manager.preview_path[:value], item)
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
124
|
def admin_partial_name(builder)
|
|
152
|
-
builder.partial ||=
|
|
153
|
-
#if template_exists?(builder.partial_name, "admin/#{resource_collection_name}", true)
|
|
154
|
-
fetch_admin_template(builder.partial_name, true)
|
|
155
|
-
end
|
|
125
|
+
builder.partial ||= fetch_admin_template(builder.partial_name, true)
|
|
156
126
|
end
|
|
157
127
|
|
|
158
128
|
def fetch_admin_template(template_name, partial=false)
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
.form-inputs
|
|
4
4
|
= f.input :email, required: false, autofocus: true
|
|
5
5
|
= f.input :password, required: false
|
|
6
|
+
- if devise_mapping.try(:two_factor_authenticatable?)
|
|
7
|
+
= f.input :otp_attempt, required: false
|
|
6
8
|
= f.input :remember_me, as: :boolean, wrapper: :default if devise_mapping.rememberable?
|
|
7
9
|
= f.button :submit, t('admin.auth.sessions.button', default: 'Sign in'), class: 'btn-primary btn-large'
|
|
8
10
|
br
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
a.thumbnail href=asset.url target='_blank' = image_tag(asset.thumb_url)
|
|
8
8
|
.span8
|
|
9
9
|
- if first_locale == l
|
|
10
|
-
|
|
10
|
+
.muted= asset.original_name
|
|
11
|
+
div= text_field :data, :human_filename, index: asset.id, value: asset.human_filename, placeholder: Asset.han(:data_file_name), style: 'width: 95%;'
|
|
11
12
|
- [:alt, :name].each do |attr|
|
|
12
13
|
- loc_attr = "#{attr}_#{l}"
|
|
13
14
|
p= text_field :data, loc_attr, index: asset.id, value: asset.send(loc_attr), placeholder: Asset.han(attr), style: 'width: 95%;'
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
div
|
|
6
6
|
= f.submit t('admin.search.submit'), class: 'btn btn-success search-submit'
|
|
7
7
|
button.js-search-cancel.btn.search-cancel= icon('remove')
|
|
8
|
-
= render 'search_form', f: f
|
|
8
|
+
= render settings[:search_form_name] || 'search_form', f: f
|
|
9
9
|
div
|
|
10
10
|
= f.submit t('admin.search.submit'), class: 'btn btn-success search-submit'
|
|
11
11
|
button.js-search-cancel.btn.search-cancel= icon('remove')
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
$('#<%= form_wrap_id %>').remove();
|
|
11
11
|
$('#list tbody:first').prepend('<%= j html %>');
|
|
12
12
|
$(document).trigger('admin:list_init');
|
|
13
|
-
$('#<%= dom_id(resource, 'list') %>').addClass('
|
|
13
|
+
$('#<%= dom_id(resource, 'list') %>').addClass('bg-lemon');
|
|
14
14
|
<% end %>
|
|
15
15
|
|
|
16
16
|
window.ab_admin_last_created = <%= raw resource.for_input_token.to_json %>;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
%>
|
|
11
11
|
$('#<%= form_wrap_id %>').remove();
|
|
12
12
|
$('#<%= el_id %>').after('<%= j html %>');
|
|
13
|
-
$('#<%= form_wrap_id %> td
|
|
13
|
+
$('#<%= form_wrap_id %> > td').attr('colspan', $('#list > thead > tr:first th').length);
|
|
14
14
|
$('#<%= form_wrap_id %> form').trigger('admin:form_init');
|
|
15
15
|
$('#<%= el_id %>').scrollToEl();
|
|
16
16
|
<% end %>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
%>
|
|
10
10
|
$('#<%= form_wrap_id %>').remove();
|
|
11
11
|
$('#list tbody:first').prepend('<%= j html %>');
|
|
12
|
-
$('#<%= form_wrap_id %> td
|
|
12
|
+
$('#<%= form_wrap_id %> > td').attr('colspan', $('#list > thead > tr > th').length);
|
|
13
13
|
$('#<%= form_wrap_id %> form').trigger('admin:form_init');
|
|
14
14
|
<% end %>
|
|
15
15
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
<%= render 'admin/shared/flash' %>
|
|
2
|
+
|
|
1
3
|
<% if params[:flash] %>
|
|
2
4
|
flash("<%= t("flash.admin.actions.#{action_name}.notice", resource_name: resource_class.model_name.human(count: 1)) %>")
|
|
3
5
|
<% end %>
|
|
4
6
|
|
|
5
|
-
|
|
6
7
|
<% unless params[:modal] %>
|
|
7
8
|
<%
|
|
8
9
|
form_wrap_id = dom_id(resource, 'list_edit')
|
|
@@ -12,8 +13,7 @@
|
|
|
12
13
|
$('#<%= dom_id(resource, 'list') %>').replaceWith('<%= j html %>');
|
|
13
14
|
var $el = $('#<%= dom_id(resource, 'list') %>');
|
|
14
15
|
$(document).trigger('admin:list_init');
|
|
15
|
-
|
|
16
|
-
$el.scrollToEl();
|
|
16
|
+
$el.addClass('bg-lemon');
|
|
17
17
|
<% end %>
|
|
18
18
|
|
|
19
19
|
window.ab_admin_last_updated = <%= raw resource.for_input_token.to_json %>;
|
|
@@ -19,12 +19,15 @@
|
|
|
19
19
|
tbody
|
|
20
20
|
- is_edit_link = manager.actions.include?(:edit)
|
|
21
21
|
- collection.each do |item|
|
|
22
|
-
tr id=dom_id(item, 'list') class=(
|
|
22
|
+
tr id=dom_id(item, 'list') class=method_or_proc_on(table_builder.row_html_class, item)
|
|
23
23
|
= batch_action_item(item)
|
|
24
|
-
td
|
|
24
|
+
td
|
|
25
|
+
= id_link(item, edit: is_edit_link)
|
|
26
|
+
- if settings[:id_column_with_created_at]
|
|
27
|
+
div: i= l(item.created_at, format: AbAdmin.datetime_format)
|
|
25
28
|
= item_index_actions_panel(item)
|
|
26
29
|
- table_builder.fields.each do |field|
|
|
27
|
-
td class=
|
|
30
|
+
td class=field.options[:cell_html_class]
|
|
28
31
|
- field_content = table_item_field(item, field)
|
|
29
32
|
- if field_content.present? && field.options[:copy_button]
|
|
30
33
|
- field_id = dom_id(item, field.name)
|
|
@@ -5,22 +5,21 @@
|
|
|
5
5
|
= t 'admin.batch_actions.title'
|
|
6
6
|
span.caret
|
|
7
7
|
ul.dropdown-menu
|
|
8
|
-
-
|
|
8
|
+
- batch_actions.each do |ba|
|
|
9
9
|
li: a.batch_action_link href='#' data-form=ba.form data-action=ba.name data-confirm=ba.confirm = ba.title
|
|
10
10
|
- if settings[:button_scopes] && button_scopes.present?
|
|
11
11
|
.btn-group
|
|
12
|
-
- button_scopes.each do |
|
|
13
|
-
- next
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
- scope_count = scope.send(*[opts[:badge][:value_type] || :count, opts[:badge][:column]].compact)
|
|
12
|
+
- button_scopes.each do |s|
|
|
13
|
+
- next unless option_conditions_met?(s.options)
|
|
14
|
+
- active = params[s.param_name]
|
|
15
|
+
- url = url_for(s.param_name => (active ? nil : 1), index_view: params[:index_view])
|
|
16
|
+
a.btn href=url title=s.options[:title] class=[s.options[:class], ('active' if active), ('tool tool-bottom' if s.options[:title])]
|
|
17
|
+
= s.options[:label] || s.options[:title] || t("admin.scopes.#{s.name}", default: s.name.to_s.titleize)
|
|
18
|
+
- if s.options[:badge]
|
|
19
|
+
- scope = s.apply(self, resource_class.accessible_by(current_ability))
|
|
20
|
+
- scope_count = scope.send(*[s.options[:badge][:value_type] || :count, s.options[:badge][:column]].compact)
|
|
22
21
|
- unless scope_count.zero?
|
|
23
|
-
span.badge< class=("badge-#{
|
|
22
|
+
span.badge< class=("badge-#{s.options.dig(:badge, :type) || 'important'} #{'pulse' if s.options.dig(:badge, :pulse)}") = scope_count
|
|
24
23
|
|
|
25
24
|
- if settings[:current_index_view] == :table
|
|
26
25
|
.btn-group#columns_hider_wrap
|
|
@@ -38,7 +37,7 @@
|
|
|
38
37
|
- settings[:index_views].each do |index_view|
|
|
39
38
|
= index_view_link(index_view)
|
|
40
39
|
|
|
41
|
-
- if can?(:export, resource_class)
|
|
40
|
+
- if settings[:export] && can?(:export, resource_class)
|
|
42
41
|
.btn-group.downloads
|
|
43
42
|
= icon('download-alt')
|
|
44
43
|
- %w(csv xlsx).each do |format|
|
|
@@ -56,6 +55,14 @@
|
|
|
56
55
|
.label> class=(ag[:css] || 'label-success')
|
|
57
56
|
=> ag[:label] || "#{ag[:column].to_s.humanize}:"
|
|
58
57
|
- if !ag[:type] || ag[:type] == :sum
|
|
59
|
-
= search_collection.distinct(false).sum(ag[:column])
|
|
58
|
+
- res = search_collection.unscope(:includes).distinct(false).sum(ag[:column])
|
|
59
|
+
= number_with_delimiter(res.round(2), delimiter: ' ') if res
|
|
60
60
|
- elsif ag[:type] == :average
|
|
61
|
-
= search_collection.average(ag[:column])
|
|
61
|
+
- res = search_collection.unscope(:includes).average(ag[:column])
|
|
62
|
+
= number_with_delimiter(res.round(2), delimiter: ' ') if res
|
|
63
|
+
- elsif ag[:type] == :pct
|
|
64
|
+
- sc_count = search_collection.count
|
|
65
|
+
- if sc_count.zero?
|
|
66
|
+
| 0%
|
|
67
|
+
- else
|
|
68
|
+
= "#{(search_collection.where.not(ag[:column] => nil).count.to_f / search_collection.count * 100).try!(:round, 2)}%"
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
- return_to = params[:return_to].presence || request.referer || collection_path
|
|
2
|
-
- return_to = "#{return_to}##{dom_id(resource, 'list')}" if resource.persisted?
|
|
2
|
+
- return_to = "#{return_to.split('#', 2).first}##{dom_id(resource, 'list')}" if resource.persisted?
|
|
3
3
|
input type='hidden' name='return_to' value=return_to
|
|
4
|
+
- if settings[:safe_save] && resource.updated_at
|
|
5
|
+
input type='hidden' name='last_updated_timestamp' value=(resource.last_updated_timestamp || resource.updated_timestamp.to_i)
|
|
4
6
|
.form-actions
|
|
5
7
|
button.btn.btn-primary type="submit" name="_save" data-disable-with=t('admin.form.save')
|
|
6
8
|
= icon('ok', true)
|
|
7
9
|
= t('admin.form.save')
|
|
10
|
+
- if resource.errors.of_kind?(:base, :changed)
|
|
11
|
+
a.btn href=edit_resource_path(resource, return_to: params[:return_to])
|
|
12
|
+
= icon('repeat')
|
|
13
|
+
= t('admin.form.refresh')
|
|
14
|
+
button.btn.btn-warning type="submit" name="_force_save" data-disable-with='Force'
|
|
15
|
+
= icon('fire', true)
|
|
16
|
+
= t('admin.form.force_save')
|
|
8
17
|
span.extra_buttons
|
|
9
18
|
- unless resource.new_record?
|
|
10
19
|
span.next_prev_buttons
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
= f.input :locale, collection: AbAdmin.translated_locales
|
|
19
19
|
= f.input :bg_color, as: :color
|
|
20
20
|
|
|
21
|
-
= f.input :password, input_html: {autocomplete: '
|
|
22
|
-
= f.input :password_confirmation, input_html: {autocomplete: '
|
|
21
|
+
= f.input :password, input_html: {autocomplete: 'new-password'}
|
|
22
|
+
= f.input :password_confirmation, input_html: {autocomplete: 'new-password'}
|
|
23
23
|
|
|
24
24
|
= f.input :avatar, as: :uploader, edit_meta: true
|
|
25
25
|
|