ab_admin 0.3.5 → 0.3.6

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 (63) hide show
  1. data/Gemfile +3 -3
  2. data/TODO +2 -1
  3. data/ab_admin.gemspec +2 -2
  4. data/app/assets/javascripts/ab_admin/components/admin_assets.js.coffee +2 -22
  5. data/app/assets/javascripts/ab_admin/components/croppable_image.js.coffee +3 -3
  6. data/app/assets/javascripts/ab_admin/components/gmaps.js.coffee +0 -38
  7. data/app/assets/javascripts/ab_admin/components/in_place_edit.js.coffee +2 -1
  8. data/app/assets/javascripts/ab_admin/components/init_nested_filelds.js.coffee +1 -0
  9. data/app/assets/javascripts/ab_admin/core/init.js.coffee +2 -0
  10. data/app/assets/javascripts/ab_admin/core/pjax.js.coffee +6 -6
  11. data/app/assets/javascripts/ab_admin/core/ui_utils.js.coffee +7 -7
  12. data/app/assets/javascripts/ab_admin/core/utils.js.coffee +19 -1
  13. data/app/assets/javascripts/ab_admin/core/view_layout.js.coffee +44 -0
  14. data/app/assets/stylesheets/ab_admin/bootstrap_and_overrides.css.scss +22 -0
  15. data/app/assets/stylesheets/ab_admin/components/_base.css.scss +3 -3
  16. data/app/assets/stylesheets/ab_admin/components/_form.css.scss +1 -1
  17. data/app/assets/stylesheets/ab_admin/components/_navigation.css.scss +7 -1
  18. data/app/assets/stylesheets/ab_admin/components/_table_view.css.scss +4 -0
  19. data/app/assets/stylesheets/ab_admin/components/_view_layout.css.scss +65 -0
  20. data/app/assets/stylesheets/ab_admin/fileupload.css.scss +1 -0
  21. data/app/controllers/admin/base_controller.rb +30 -14
  22. data/app/controllers/admin/static_pages_controller.rb +3 -1
  23. data/app/views/admin/base/_search_layout.html.slim +2 -0
  24. data/app/views/admin/base/create.js.erb +2 -2
  25. data/app/views/admin/base/edit.js.erb +3 -1
  26. data/app/views/admin/base/index.html.slim +5 -0
  27. data/app/views/admin/base/new.js.erb +3 -1
  28. data/app/views/admin/base/update.js.erb +1 -1
  29. data/app/views/admin/fileupload/_file.html.slim +1 -1
  30. data/app/views/admin/fileupload/_video.html.slim +9 -0
  31. data/app/views/admin/fileupload/_vtmpl.html.slim +10 -0
  32. data/app/views/admin/shared/_batch_actions.html.slim +9 -3
  33. data/app/views/admin/shared/_breadcrumbs.html.slim +5 -6
  34. data/app/views/admin/shared/_flash.js.erb +3 -0
  35. data/app/views/admin/shared/inputs/_checkbox_tree.html.slim +14 -0
  36. data/app/views/admin/structures/_form.html.slim +5 -2
  37. data/app/views/layouts/admin/_footer.html.slim +1 -0
  38. data/app/views/layouts/admin/_navigation.html.slim +5 -7
  39. data/app/views/layouts/admin/application.html.slim +1 -1
  40. data/config/locales/en.yml +4 -10
  41. data/config/locales/it.yml +1 -8
  42. data/config/locales/ru.yml +4 -10
  43. data/features/dsl/export.feature +6 -6
  44. data/lib/ab_admin/concerns/utilities.rb +3 -3
  45. data/lib/ab_admin/controllers/head_options.rb +1 -0
  46. data/lib/ab_admin/core_ext/string.rb +3 -2
  47. data/lib/ab_admin/hooks/paginate_hooks.rb +1 -0
  48. data/lib/ab_admin/models/asset.rb +4 -0
  49. data/lib/ab_admin/models/attachment_file.rb +0 -4
  50. data/lib/ab_admin/models/type_model.rb +10 -0
  51. data/lib/ab_admin/models/user.rb +1 -1
  52. data/lib/ab_admin/utils.rb +2 -0
  53. data/lib/ab_admin/version.rb +1 -1
  54. data/lib/ab_admin/views/admin_helpers.rb +14 -6
  55. data/lib/ab_admin/views/admin_navigation_helpers.rb +4 -2
  56. data/lib/ab_admin/views/form_builder.rb +5 -2
  57. data/lib/ab_admin/views/helpers.rb +4 -0
  58. data/lib/ab_admin/views/inputs/ckeditor_input.rb +0 -1
  59. data/lib/generators/ab_admin/install/templates/config/nginx.conf +12 -7
  60. data/lib/generators/ab_admin/install/templates/models/structure.rb +2 -1
  61. data/lib/generators/ab_admin/resource/templates/_form.haml.erb +1 -1
  62. data/lib/generators/ab_admin/resource/templates/_form.slim.erb +1 -1
  63. metadata +12 -22
@@ -59,6 +59,7 @@
59
59
  padding-top: 10px;
60
60
  padding-left: 5px;
61
61
  z-index: 2;
62
+ position: relative;
62
63
  }
63
64
  .fileupload-button {
64
65
  z-index: 3;
@@ -93,6 +93,10 @@ class Admin::BaseController < ::InheritedResources::Base
93
93
 
94
94
  protected
95
95
 
96
+ def default_url_options
97
+ {format: nil}
98
+ end
99
+
96
100
  def batch_action_list
97
101
  self.class.batch_action_list ||= begin
98
102
  resource_class.batch_actions.map do |a|
@@ -106,6 +110,7 @@ class Admin::BaseController < ::InheritedResources::Base
106
110
  super
107
111
  base.class_eval do
108
112
  before_create :bind_current_user
113
+ before_save :bind_current_updater
109
114
  end
110
115
  end
111
116
 
@@ -126,16 +131,6 @@ class Admin::BaseController < ::InheritedResources::Base
126
131
  export_builder.render_options
127
132
  end
128
133
 
129
- def set_title
130
- name_for_lookup = params[:custom_action] || action_name
131
- lookups = [:"admin.#{controller_name}.actions.#{name_for_lookup}.title",
132
- :"admin.#{controller_name}.actions.#{name_for_lookup}",
133
- :"admin.actions.#{name_for_lookup}.title",
134
- :"admin.actions.#{name_for_lookup}",
135
- name_for_lookup]
136
- @page_title ||= [resource_class.model_name.human(count: 1), t(lookups.shift, default: lookups)].join(' - ')
137
- end
138
-
139
134
  def preview_resource_path(item)
140
135
  nil
141
136
  end
@@ -186,6 +181,16 @@ class Admin::BaseController < ::InheritedResources::Base
186
181
  end
187
182
  end
188
183
 
184
+ def set_title
185
+ name_for_lookup = params[:custom_action] || action_name
186
+ lookups = [:"admin.#{controller_name}.actions.#{name_for_lookup}.title",
187
+ :"admin.#{controller_name}.actions.#{name_for_lookup}",
188
+ :"admin.actions.#{name_for_lookup}.title",
189
+ :"admin.actions.#{name_for_lookup}",
190
+ name_for_lookup]
191
+ @page_title ||= t(lookups.shift, default: lookups)
192
+ end
193
+
189
194
  def parent_collection_path
190
195
  {action: :index, controller: "admin/#{parent_class.model_name.plural}"}
191
196
  end
@@ -215,7 +220,11 @@ class Admin::BaseController < ::InheritedResources::Base
215
220
  end
216
221
 
217
222
  def set_layout
218
- request.headers['X-PJAX'] ? false : 'admin/application'
223
+ pjax? ? false : 'admin/application'
224
+ end
225
+
226
+ def pjax?
227
+ request.headers['X-PJAX']
219
228
  end
220
229
 
221
230
  def back_or_collection
@@ -272,6 +281,10 @@ class Admin::BaseController < ::InheritedResources::Base
272
281
  resource.user_id = current_user.id if resource.respond_to?(:user_id)
273
282
  end
274
283
 
284
+ def bind_current_updater(*args)
285
+ resource.updater_id = current_user.id if resource.respond_to?(:updater_id)
286
+ end
287
+
275
288
  def xhr?
276
289
  request.xhr?
277
290
  end
@@ -303,9 +316,12 @@ class Admin::BaseController < ::InheritedResources::Base
303
316
  def render_unauthorized(exception)
304
317
  Rails.logger.debug "Access denied on #{exception.action} #{exception.subject.inspect}, user: #{current_user.try(:id)}"
305
318
 
306
- respond_to do |format|
307
- format.html { redirect_to (moderator? ? admin_root_path : root_path), alert: exception.message }
308
- format.any { head :unauthorized }
319
+ if pjax?
320
+ render partial: 'admin/shared/flash', locals: {flash: {alert: exception.message}}
321
+ elsif request.format.try(:html?)
322
+ redirect_to (moderator? ? admin_root_path : root_path), alert: exception.message
323
+ else
324
+ head :unauthorized
309
325
  end
310
326
  end
311
327
 
@@ -1,7 +1,9 @@
1
1
  class Admin::StaticPagesController < Admin::BaseController
2
2
  load_and_authorize_resource
3
3
 
4
- belongs_to :structure, singleton: true
4
+ defaults singleton: true
5
+
6
+ belongs_to :structure
5
7
 
6
8
  def settings
7
9
  {}
@@ -1,3 +1,5 @@
1
+ #toggle_sidebar_off.btn.btn-large = icon('chevron-left')
2
+ #toggle_sidebar_on.btn.btn-large = icon('chevron-right')
1
3
  h3= t('admin.search.title')
2
4
  = search_admin_form_for @search, url: collection_path do |f|
3
5
  - cache [I18n.locale, 'search_form_inside', resource_class.name, params[:q].hash] do
@@ -1,8 +1,8 @@
1
1
  <%
2
2
  form_wrap_id = dom_id(resource_class.new, 'list_edit')
3
- html = render('table', collection: [resource])[/<tr id[^>]+>.*<\/tr>/m].html_safe
3
+ html = render('table', collection: [resource]).match(/<tbody>(.*)<\/tbody>/m)[1].html_safe
4
4
  %>
5
5
  $('#<%= form_wrap_id %>').remove();
6
6
  $('#list tbody').prepend('<%= j html %>');
7
7
  $('#<%= dom_id(resource, 'list') %>').addClass('success').scrollToEl();
8
- $(document).trigger('admin:list_init');
8
+ $(document).trigger('admin:list_init');
@@ -5,6 +5,8 @@
5
5
  %>
6
6
  $('#<%= form_wrap_id %>').remove();
7
7
  $('#<%= el_id %>').after('<%= j html %>');
8
- $('#<%= form_wrap_id %> td').attr('colspan', $('#list tr:first th').length);
8
+ $('#<%= form_wrap_id %> td:first').attr('colspan', $('#list tr:first th').length);
9
9
  $('#<%= el_id %>').scrollToEl();
10
10
  $('#<%= form_wrap_id %> form').trigger('admin:form_init');
11
+
12
+ <%= render 'admin/shared/flash', flash: flash %>
@@ -11,3 +11,8 @@
11
11
  .btn-group
12
12
  - [50, 100, 500, 1000].each do |c|
13
13
  a.btn.per_page data-val=c href=url_for(params.merge(per_page: c)) class=('active' if c == collection.per_page) = c
14
+
15
+ - if pjax? && flash.present?
16
+ - flash.each do |k, v|
17
+ = javascript_tag %[flash("#{j v}", "#{k}")]
18
+
@@ -4,5 +4,7 @@
4
4
  %>
5
5
  $('#<%= form_wrap_id %>').remove();
6
6
  $('#list tbody').prepend('<%= j html %>');
7
- $('#<%= form_wrap_id %> td').attr('colspan', $('#list tr:first th').length);
7
+ $('#<%= form_wrap_id %> td:first').attr('colspan', $('#list tr:first th').length);
8
8
  $('#<%= form_wrap_id %> form').trigger('admin:form_init');
9
+
10
+ <%= render 'admin/shared/flash', flash: flash %>
@@ -1,6 +1,6 @@
1
1
  <%
2
2
  form_wrap_id = dom_id(resource, 'list_edit')
3
- html = render('table', collection: [resource])[/<tr id[^>]+>.*<\/tr>/m].html_safe
3
+ html = render('table', collection: [resource]).match(/<tbody>(.*)<\/tbody>/m)[1].html_safe
4
4
  %>
5
5
  $('#<%= form_wrap_id %>').remove();
6
6
  $('#<%= dom_id(resource, 'list') %>').replaceWith('<%= j html %>');
@@ -1,5 +1,5 @@
1
1
  .asset id="asset_#{file.id}" data-id=file.id
2
- a href=file.url target='_blank' = file.original_name
2
+ a href=file.url target='_blank' = file.human_name
3
3
  span== " (#{file.human_filesize}) - #{l(file.created_at, format: :long)}"
4
4
  = link_to icon('remove', true), admin_asset_path(file), remote: true, method: :delete, \
5
5
  class: 'del_asset btn btn-danger btn-mini', data: {confirm: t('admin.delete_confirmation')}
@@ -0,0 +1,9 @@
1
+ .asset id="asset_#{video.id}" data-id=video.id
2
+ = link_to icon('remove', true), admin_asset_path(video), remote: true, method: :delete, title: t('admin.delete'), class: 'del_asset', \
3
+ data: {confirm: t('admin.delete_confirmation')}
4
+ video controls='true'
5
+ source src=video.url
6
+ | Your browser does not support mp4 videos
7
+ .video-filename
8
+ a href=video.url target='_blank' = video.human_name
9
+ span== " (#{video.human_filesize}) - #{l(video.created_at, format: :long)}"
@@ -0,0 +1,10 @@
1
+ script#fileupload_vtmpl type="text/x-jquery-tmpl"
2
+ .asset id="asset_${id}" data-id='${id}'
3
+ = link_to icon('remove', true), '/admin/assets/${id}', remote: true, method: :delete, title: t('admin.delete'), \
4
+ class: 'del_asset btn btn-danger btn-mini', data: {confirm: t('admin.delete_confirmation')}
5
+ video controls='true'
6
+ source src='${url}'
7
+ | Your browser does not support mp4 videos
8
+ .video-filename
9
+ a href='${url}' target='_blank' ${original_name}
10
+ span &nbsp;(${human_filesize})
@@ -12,10 +12,16 @@
12
12
  - button_scopes.each do |name, opts|
13
13
  - active = params[opts[:as]]
14
14
  a.btn[href=(url_for(opts[:as] => (active ? nil : 1))) class=('active' if active)]= t "admin.scopes.#{name}"
15
+
16
+ a.btn.pull-left#columns_hider_show[href="#columns_hider" data-toggle='modal']= t 'admin.columns_hider.button'
17
+
18
+ .btn-group#view_layout
19
+ .btn data-css='main_wide' = icon('align-left')
20
+ .btn data-css='main_reverse' = icon('align-right')
21
+
15
22
  .btn-group.downloads
16
23
  = icon('download-alt')
17
- - %w(csv xls json).each do |format|
24
+ /- %w(csv xls json).each do |format|
25
+ - %w(csv xls).each do |format|
18
26
  - next if format == 'xls' && !defined?(Mime::XLSX)
19
27
  = link_to format, params.merge(format: format), id: "export_#{format}"
20
- a.btn.pull-right#columns_hider_show[href="#columns_hider" data-toggle='modal']= t 'admin.columns_hider.button'
21
-
@@ -1,7 +1,6 @@
1
1
  - if @breadcrumbs.present?
2
- ul.breadcrumb
3
- - @breadcrumbs[0..-2].each do |crumb|
4
- li
5
- = link_to crumb[:name], crumb[:url], crumb[:options]
6
- span.divider &nbsp;/&nbsp;
7
- li.active= link_to @breadcrumbs.last[:name], @breadcrumbs.last[:url], @breadcrumbs.last[:options]
2
+ - @breadcrumbs[0..-2].each do |crumb|
3
+ li
4
+ = link_to crumb[:name], crumb[:url], crumb[:options]
5
+ span.divider &nbsp;/&nbsp;
6
+ li.active= link_to [@breadcrumbs.last[:name] || @breadcrumbs.last[:url], @page_title].join(' - '), @breadcrumbs.last[:url], @breadcrumbs.last[:options]
@@ -0,0 +1,3 @@
1
+ <% flash.each do |k, v| %>
2
+ flash("<%= j v %>", "<%= k %>");
3
+ <% end unless flash.empty? %>
@@ -0,0 +1,14 @@
1
+ - attr_ids_method = "#{attribute_name.to_s.singularize}_ids"
2
+ - attr_ids = f.object.send(attr_ids_method)
3
+ - attr_name = "#{f.object_name}[#{attr_ids_method}][]"
4
+ - opts = reflection.options.slice(:conditions, :order)
5
+
6
+ - reflection.klass.roots.all(opts).each do |root|
7
+ .checkbox_tree_input
8
+ label.checkbox
9
+ = check_box_tag attr_name, root.id, attr_ids.include?(root.id)
10
+ b= AbAdmin.display_name(root)
11
+ - root.children.all(opts).each do |child|
12
+ label.checkbox
13
+ = check_box_tag attr_name, child.id, attr_ids.include?(child.id)
14
+ = AbAdmin.display_name(child)
@@ -1,7 +1,7 @@
1
1
  = admin_form_for @structure do |f|
2
2
  = f.locale_tabs do |l|
3
3
  = f.input :title, locale: l
4
- = f.input :redirect_url, locale: l
4
+ = f.input :redirect_url, locale: l, as: :string
5
5
 
6
6
  = f.input :slug
7
7
  - if @structure.moveable?
@@ -11,9 +11,12 @@
11
11
 
12
12
  = f.input :is_visible
13
13
 
14
- = input_set t('admin.pictures') do
14
+ = input_set ha(:picture) do
15
15
  = f.attach_file_field :picture, file_max_size: 2
16
16
 
17
+ = input_set ha(:pictures) do
18
+ = f.attach_file_field :pictures, file_max_size: 2
19
+
17
20
  = input_set t('admin.keywords') do
18
21
  = render 'admin/headers/form', f: f
19
22
 
@@ -5,6 +5,7 @@ footer
5
5
  = cache [I18n.locale, 'admin', 'footer'] do
6
6
  = render 'admin/fileupload/tmpl'
7
7
  = render 'admin/fileupload/ftmpl'
8
+ = render 'admin/fileupload/vtmpl'
8
9
  = render 'admin/shared/columns_hider'
9
10
 
10
11
  - unless admin?
@@ -20,11 +20,9 @@ header.navbar
20
20
  li.divider
21
21
  li= link_to(t('admin.auth.sign_out'), destroy_user_session_path, method: 'delete')
22
22
 
23
- = render 'admin/shared/breadcrumbs'
23
+ ul.breadcrumb
24
+ li.resource_actions
25
+ - action_items.each do |act|
26
+ = action_link(act)
27
+ = render 'admin/shared/breadcrumbs'
24
28
 
25
- .top_bar.clearfix
26
- .resource_actions
27
- - action_items.each do |act|
28
- = action_link(act)
29
- .resource_title
30
- h1= @page_title
@@ -17,8 +17,8 @@ html id="controller_#{controller_name}"
17
17
  = render 'layouts/admin/navigation'
18
18
  #main role="main"
19
19
  .container-fluid
20
+ = render('admin/shared/flash', flash: flash) if flash
20
21
  #container.row-fluid
21
- = render('admin/shared/flash', flash: flash) if flash
22
22
  .wrap_content
23
23
  .clearfix[data-pjax-container=true class=layout_css]= yield
24
24
  - if collection_action? && settings[:search]
@@ -197,14 +197,8 @@ en:
197
197
  deleted: Removed
198
198
  pending: Inactive
199
199
  suspended: Frozen
200
- versions:
201
- current: "The current version of"
202
- item: Element
203
- modified_at: "Date of editing"
204
- modified_by: "Edited (a)"
205
- title: Story
206
- type: Type
207
200
  admin_js:
201
+ empty: Empty
208
202
  add_link: Create?
209
203
  button_description: Description
210
204
  button_name_add: Add
@@ -295,8 +289,8 @@ en:
295
289
  updating: "Update ..."
296
290
  "yes": "Yes"
297
291
  will_paginate:
298
- next_label: "Next. →"
299
292
  page_gap: "..."
300
- pagination_info: "Displaying <b>%{from}&nbsp;-&nbsp;%{to}</b> of %{count} total"
293
+ pagination_info: "<b>%{from}&nbsp;-&nbsp;%{to}</b> of <b>%{count}</b>"
301
294
  pagination_info_empty: "0 total"
302
- previous_label: "← Prev."
295
+ next_label: ""
296
+ previous_label: "←"
@@ -211,14 +211,7 @@ it:
211
211
  deleted: Rimosso
212
212
  pending: Inattivo
213
213
  suspended: Congelato
214
- versions:
215
- current: La versione corrente di
216
- item: Elemento
217
- modified_at: Data di modifica
218
- modified_by: Edited (a)
219
- title: Storia
220
- type: Tipo
221
- admin_js:
214
+ admin_js:
222
215
  add_link: Crea?
223
216
  button_description: Descrizione
224
217
  button_name_add: Aggiungere
@@ -188,13 +188,6 @@ ru:
188
188
  deleted: "Удален"
189
189
  pending: "Неактивирован"
190
190
  suspended: "Заморожен"
191
- versions:
192
- current: "Текущая версия"
193
- item: "Элемент"
194
- modified_at: "Дата редактирования"
195
- modified_by: "Редактировал(а)"
196
- title: "История"
197
- type: "Тип"
198
191
  structure:
199
192
  kind:
200
193
  group: "Группа страницек"
@@ -207,6 +200,7 @@ ru:
207
200
  default: "По умолчанию"
208
201
  menu: "Меню"
209
202
  admin_js:
203
+ empty: Пусто
210
204
  add_link: "Создать?"
211
205
  button_description: "Описание"
212
206
  button_name_add: "Добавить"
@@ -290,11 +284,11 @@ ru:
290
284
  updating: "Обновление..."
291
285
  "yes": "Да"
292
286
  will_paginate:
293
- next_label: "След. &#8594;"
294
287
  page_gap: "&hellip;"
295
- pagination_info: "Показано <b>%{from}&nbsp;-&nbsp;%{to}</b> из <b>%{count}</b> всего"
288
+ pagination_info: "<b>%{from}&nbsp;-&nbsp;%{to}</b> из <b>%{count}</b>"
296
289
  pagination_info_empty: "0 всего"
297
- previous_label: "&#8592; Пред."
290
+ next_label: ""
291
+ previous_label: "←"
298
292
 
299
293
  errors:
300
294
  messages:
@@ -28,12 +28,12 @@ Feature: Export
28
28
  And should see "$234"
29
29
  And should see "Chair"
30
30
 
31
- Scenario: Export to json format
32
- When I am on the admin products page
33
- And I follow "export_json"
34
- Then should see "t-12"
35
- And should see "234"
36
- And should see "Chair"
31
+ # Scenario: Export to json format
32
+ # When I am on the admin products page
33
+ # And I follow "export_json"
34
+ # Then should see "t-12"
35
+ # And should see "234"
36
+ # And should see "Chair"
37
37
 
38
38
  Scenario: Export to xls format
39
39
  When I am on the admin products page
@@ -10,17 +10,17 @@ module AbAdmin
10
10
 
11
11
  module ClassMethods
12
12
  def max_time
13
- Rails.cache.fetch("by_class_#{name}", expires_in: 60) { maximum(:updated_at).to_i }
13
+ Rails.cache.fetch("by_class_#{name}", expires_in: 60) { unscoped.maximum(:updated_at).to_i }
14
14
  end
15
15
 
16
16
  def max_time_by_scope(scope)
17
- Rails.cache.fetch("by_class_#{name}_#{scope}", expires_in: 60) { send(scope).maximum(:updated_at).to_i }
17
+ Rails.cache.fetch("by_class_#{name}_#{scope}", expires_in: 60) { unscoped.send(scope).maximum(:updated_at).to_i }
18
18
  end
19
19
 
20
20
  def full_truncate
21
21
  destroy_all
22
22
  truncate!
23
- const_get(:Translation).truncate! if translates?
23
+ const_get(:Translation).truncate! if respond_to?(:translates?) && translates?
24
24
  end
25
25
 
26
26
  def all_ids