adminpanel 2.4.3 → 2.5.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/README.md +16 -16
  4. data/adminpanel.gemspec +9 -8
  5. data/app/assets/javascripts/adminpanel/application.js +4 -0
  6. data/app/assets/javascripts/adminpanel/bootstrap-wysihtml5.js +2 -4
  7. data/app/assets/javascripts/adminpanel/sortable.js.coffee +27 -0
  8. data/app/assets/stylesheets/adminpanel/application.css +1 -0
  9. data/app/assets/stylesheets/adminpanel/sortable.css.scss.erb +13 -0
  10. data/app/controllers/adminpanel/application_controller.rb +0 -1
  11. data/app/controllers/adminpanel/sessions_controller.rb +5 -2
  12. data/app/controllers/concerns/adminpanel/rest_actions.rb +24 -22
  13. data/app/controllers/concerns/adminpanel/sortable_actions.rb +3 -20
  14. data/app/helpers/adminpanel/breadcrumbs_helper.rb +6 -5
  15. data/app/helpers/adminpanel/router_helper.rb +9 -3
  16. data/app/helpers/adminpanel/shared_pages_helper.rb +1 -1
  17. data/app/models/concerns/adminpanel/base.rb +34 -11
  18. data/app/models/concerns/adminpanel/sitemap.rb +0 -1
  19. data/app/models/concerns/adminpanel/sortable.rb +33 -30
  20. data/app/models/concerns/adminpanel/sortable_gallery.rb +90 -0
  21. data/app/views/adminpanel/form/_adminpanel_file_field.html.erb +1 -1
  22. data/app/views/adminpanel/templates/index.html.erb +41 -13
  23. data/app/views/adminpanel/templates/show.html.erb +33 -13
  24. data/config/initializers/adminpanel/carrierwave_mini_magick_quality.rb +11 -0
  25. data/config/locales/en.yml +3 -7
  26. data/config/locales/es.yml +1 -8
  27. data/config/routes.rb +6 -8
  28. data/lib/adminpanel.rb +9 -8
  29. data/lib/adminpanel/version.rb +1 -1
  30. data/lib/generators/adminpanel/custom_errors/custom_errors_generator.rb +37 -0
  31. data/lib/generators/adminpanel/custom_errors/templates/errors_controller.rb +14 -0
  32. data/lib/generators/adminpanel/custom_errors/templates/show.html.erb +1 -0
  33. data/lib/generators/adminpanel/gallery/templates/gallery_template.rb +8 -3
  34. data/lib/generators/adminpanel/gallery/templates/uploader.rb +4 -1
  35. data/lib/generators/adminpanel/initialize/initialize_generator.rb +0 -12
  36. data/lib/generators/adminpanel/initialize/templates/adminpanel_setup.rb +1 -2
  37. data/lib/generators/adminpanel/resource/resource_generator.rb +29 -8
  38. data/lib/generators/adminpanel/resource/resource_generator_helper.rb +34 -7
  39. data/lib/generators/adminpanel/resource/templates/adminpanel_resource_template.rb +7 -2
  40. data/lib/tasks/adminpanel/adminpanel.rake +19 -61
  41. data/test/dummy/app/models/adminpanel/file_resourcefile.rb +1 -1
  42. data/test/dummy/app/models/adminpanel/gallery.rb +9 -4
  43. data/test/dummy/app/models/adminpanel/galleryfile.rb +2 -2
  44. data/test/dummy/app/models/adminpanel/photo.rb +1 -1
  45. data/test/dummy/app/models/adminpanel/product.rb +0 -4
  46. data/test/dummy/config/initializers/adminpanel_setup.rb +1 -1
  47. data/test/dummy/test/fixtures/adminpanel/galleryfiles.yml +24 -0
  48. data/test/features/shared/concerns/sortable_gallery_ui_test.rb +25 -0
  49. data/test/features/shared/concerns/sortable_test.rb +4 -4
  50. data/test/features/shared/form/{belongs_to_non_category_modal_test.rb → belongs_to_remote_test.rb} +1 -1
  51. data/test/features/shared/form/{has_many_through_non_category_modal_test.rb → has_many_through_remote_test.rb} +1 -1
  52. data/test/generators/dump_generator_test.rb +1 -13
  53. data/test/generators/gallery_generator_test.rb +1 -1
  54. data/test/generators/initialize_generator_test.rb +1 -9
  55. data/test/generators/resource_generator_test.rb +21 -1
  56. data/test/helpers/router_helper_test.rb +0 -4
  57. data/test/models/adminpanel/sortable_gallery_unit_test.rb +118 -0
  58. data/test/models/adminpanel/sortable_unit_test.rb +75 -0
  59. data/test/tasks/adminpanel_rake_test.rb +1 -1
  60. metadata +86 -85
  61. data/app/assets/images/adminpanel/loguito.png +0 -0
  62. data/app/controllers/adminpanel/categories_controller.rb +0 -52
  63. data/app/controllers/concerns/adminpanel/galleryzable_actions.rb +0 -34
  64. data/app/models/concerns/adminpanel/galleryzation.rb +0 -78
  65. data/app/views/adminpanel/categories/_categories_table.html.erb +0 -48
  66. data/app/views/adminpanel/categories/_category_form.html.erb +0 -33
  67. data/app/views/adminpanel/categories/create.js.erb +0 -6
  68. data/app/views/adminpanel/categories/index.html.erb +0 -63
  69. data/app/views/adminpanel/categories/new.js.erb +0 -5
  70. data/app/views/adminpanel/icons/_move_to_better.html.erb +0 -17
  71. data/app/views/adminpanel/icons/_move_to_worst.html.erb +0 -18
  72. data/app/views/adminpanel/shared/_gallery_entries.html.erb +0 -11
  73. data/app/views/adminpanel/shared/_index_records.html.erb +0 -32
  74. data/app/views/adminpanel/templates/gallery_entries.js.erb +0 -1
  75. data/app/views/adminpanel/templates/index_records.js.erb +0 -1
  76. data/lib/generators/adminpanel/initialize/templates/category_template.rb +0 -45
  77. data/lib/generators/adminpanel/initialize/templates/create_adminpanel_categories_table.rb +0 -11
  78. data/test/features/categories/categories_index_test.rb +0 -31
  79. data/test/features/shared/concerns/galleryzable_test.rb +0 -22
  80. data/test/features/shared/form/belongs_to_category_modal_test.rb +0 -35
  81. data/test/features/shared/form/has_many_through_category_modal_test.rb +0 -35
  82. data/test/models/adminpanel/galleryzable_test.rb +0 -28
@@ -92,7 +92,7 @@ module Adminpanel
92
92
 
93
93
  def table_type(model)
94
94
  if model.is_sortable?
95
- ''
95
+ 'sortable'
96
96
  else
97
97
  'information-table'
98
98
  end
@@ -4,6 +4,8 @@ module Adminpanel
4
4
 
5
5
  # static(class) methods
6
6
  module ClassMethods
7
+
8
+ # API methods
7
9
  def mount_images(relation)
8
10
  has_many relation, dependent: :destroy
9
11
  accepts_nested_attributes_for relation, allow_destroy: true
@@ -14,6 +16,8 @@ module Adminpanel
14
16
  super(name, scope, options.reverse_merge!({touch: true}))
15
17
  end
16
18
 
19
+ # The fields and the types that should be used to generate form
20
+ # and display fields
17
21
  def form_attributes
18
22
  []
19
23
  end
@@ -24,6 +28,11 @@ module Adminpanel
24
28
  'please overwrite self.display_name'
25
29
  end
26
30
 
31
+ # side menu icon
32
+ def icon
33
+ 'truck'
34
+ end
35
+
27
36
  # The word that is going to be shown in the side menu, routes and
28
37
  # breadcrumb.
29
38
  def collection_name
@@ -41,6 +50,9 @@ module Adminpanel
41
50
  return "field #{field} 'label' property not found :("
42
51
  end
43
52
 
53
+ # returns the attributes that should be shown in the correspondin view
54
+ # (some attributes may be filtered from the index table, from the show
55
+ # or even both)
44
56
  def display_attributes(type)
45
57
  display_attributes = []
46
58
  form_attributes.each do |attribute|
@@ -57,11 +69,12 @@ module Adminpanel
57
69
  end
58
70
  end
59
71
  end
60
-
61
72
  return display_attributes
62
73
  end
63
74
 
64
- def has_images?
75
+ # return true if model has adminpanel_file_field in
76
+ # it's attributes
77
+ def has_gallery?
65
78
  form_attributes.each do |fields|
66
79
  fields.each do |attribute, properties|
67
80
  if properties['type'] == 'adminpanel_file_field'
@@ -72,7 +85,9 @@ module Adminpanel
72
85
  return false
73
86
  end
74
87
 
75
- def get_image_relationship
88
+ # returns the attribute that should be namespaced to be the class
89
+ # ex: returns 'productfiles', so class is Adminpanel::Productfile
90
+ def gallery_relationship
76
91
  form_attributes.each do |fields|
77
92
  fields.each do |attribute, properties|
78
93
  if properties['type'] == 'adminpanel_file_field'
@@ -83,6 +98,16 @@ module Adminpanel
83
98
  return false
84
99
  end
85
100
 
101
+ # gets the class gallery and return it's class
102
+ def gallery_class
103
+ "adminpanel/#{gallery_relationship}".classify.constantize
104
+ end
105
+
106
+ # returns all the class of the attributes of a given type.
107
+ # Usage:
108
+ # To get all classes of all belongs_to attributes:
109
+ # @model.relationships_of('belongs_to')
110
+ # # => ['Adminpanel::Category', Adminpanel::ModelBelongTo]
86
111
  def relationships_of(type_property)
87
112
  classes_of_relation = []
88
113
  form_attributes.each do |fields|
@@ -95,14 +120,6 @@ module Adminpanel
95
120
  return classes_of_relation
96
121
  end
97
122
 
98
- def icon
99
- 'truck'
100
- end
101
-
102
- def gallery_children
103
- nil
104
- end
105
-
106
123
  def routes_options
107
124
  { path: collection_name.parameterize }
108
125
  end
@@ -135,6 +152,12 @@ module Adminpanel
135
152
  false
136
153
  end
137
154
 
155
+ def has_sortable_gallery?
156
+ if has_gallery?
157
+ gallery_class.is_sortable?
158
+ end
159
+ end
160
+
138
161
  private
139
162
 
140
163
  def exclude?(route)
@@ -21,7 +21,6 @@ module Adminpanel
21
21
  logger.info Time.now
22
22
  ping_urls.each do |name, url|
23
23
  request = url % CGI.escape("#{root_url}/sitemap.xml")
24
- logger.info root_url
25
24
  logger.info " Pinging #{name} with #{request}"
26
25
  if !Rails.env.development?
27
26
  response = Net::HTTP.get_response(URI.parse(request))
@@ -6,58 +6,61 @@ module Adminpanel
6
6
  included do
7
7
  before_create :set_position
8
8
  before_destroy :rearrange_positions
9
-
10
- default_scope do
11
- order('position ASC')
12
- end
13
9
  end
14
10
 
15
11
  module ClassMethods
16
12
  def is_sortable?
17
13
  true
18
14
  end
19
- end
20
15
 
21
- def move_to_better_position
22
- if self.position > 1
23
- conflicting_gallery(self.position - 1).increment!(:position)
24
- self.decrement!(:position)
16
+ def ordered
17
+ order('position ASC')
18
+ end
25
19
 
26
- true
27
- else
28
- false
20
+ def in_better_position(current_position, new_position)
21
+ where(
22
+ 'position >= ? AND position < ?',
23
+ new_position,
24
+ current_position
25
+ )
26
+ end
27
+
28
+ def in_worst_position(current_position, new_position)
29
+ where(
30
+ 'position > ? AND position <= ?',
31
+ current_position,
32
+ new_position
33
+ )
29
34
  end
30
35
  end
31
36
 
32
- def move_to_worst_position
33
- records = self.class.count
34
- if self.position < records
35
- conflicting_gallery(self.position + 1).decrement!(:position)
36
- self.increment!(:position)
37
- true
37
+ def move_to_position(new_position)
38
+ if new_position < position
39
+ # search for better elements and downgrade them
40
+ self.class.in_better_position(
41
+ self.position,
42
+ new_position
43
+ ).update_all('position = position + 1')
38
44
  else
39
- false
45
+ # search for worster elements and upgrade them
46
+ self.class.in_worst_position(
47
+ self.position,
48
+ new_position
49
+ ).update_all('position = position - 1')
40
50
  end
51
+ self.update(position: new_position)
41
52
  end
42
53
 
43
54
  protected
44
- def conflicting_gallery(conflicting_position)
45
- logger.info "searching pos: #{conflicting_position}"
46
- self.class.find_by_position(conflicting_position)
47
- end
48
55
 
49
56
  def rearrange_positions
50
- unarranged_records = self.class.where(
57
+ self.class.where(
51
58
  'position > ?', self.position
52
- )
53
- unarranged_records.each do |record|
54
- record.update_attribute(:position, gallery.position - 1)
55
- end
56
-
59
+ ).update_all('position = position - 1')
57
60
  end
58
61
 
59
62
  def set_position
60
- last_record = self.class.last
63
+ last_record = self.class.ordered.last
61
64
  if last_record.nil?
62
65
  # this is the first record that is created
63
66
  self.position = 1
@@ -0,0 +1,90 @@
1
+ module Adminpanel
2
+ module SortableGallery
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ before_create :set_position
7
+ before_destroy :rearrange_positions
8
+
9
+ scope :ordered, -> { order('position ASC') }
10
+ end
11
+
12
+ module ClassMethods
13
+ def is_sortable?
14
+ true
15
+ end
16
+
17
+ def in_better_position(current_position, new_position, relation_id)
18
+ where(
19
+ 'position >= ? AND position < ?',
20
+ new_position,
21
+ current_position
22
+ ).where(
23
+ relation_field => relation_id
24
+ # => 'product_id' => member.product_id
25
+ )
26
+ end
27
+
28
+ def in_worst_position(current_position, new_position, relation_id)
29
+ where(
30
+ 'position > ? AND position <= ?',
31
+ current_position,
32
+ new_position
33
+ ).where(
34
+ relation_field => relation_id
35
+ # => 'product_id' => member.product_id
36
+ )
37
+ end
38
+ end
39
+
40
+ def move_to_position(new_position)
41
+ if new_position < position
42
+ # search for better elements and downgrade them
43
+ self.class.in_better_position(
44
+ self.position,
45
+ new_position,
46
+ self.send(self.class.relation_field)
47
+ ).update_all('position = position + 1')
48
+ else
49
+ # search for worster elements and upgrade them
50
+ self.class.in_worst_position(
51
+ self.position,
52
+ new_position,
53
+ self.send(self.class.relation_field)
54
+ ).update_all('position = position - 1')
55
+ end
56
+ self.update(position: new_position)
57
+ end
58
+
59
+ # we should detect if the name isn't defined in the class
60
+ def name
61
+ I18n.t('gallery.image')
62
+ end
63
+
64
+ protected
65
+
66
+ def rearrange_positions
67
+ self.class.where(
68
+ self.class.relation_field => self.send(
69
+ self.class.relation_field
70
+ )
71
+ ).where(
72
+ 'position > ?',
73
+ self.position
74
+ ).update_all('position = position - 1')
75
+ end
76
+
77
+ def set_position
78
+ last_record = self.class.where(
79
+ self.class.relation_field => self.send(
80
+ self.class.relation_field
81
+ )
82
+ ).ordered.last
83
+ if last_record.nil?
84
+ self.position = 1
85
+ else
86
+ self.position = last_record.position + 1
87
+ end
88
+ end
89
+ end
90
+ end
@@ -13,7 +13,7 @@
13
13
 
14
14
  <% if (
15
15
  properties['max-files'].to_i != 0 &&
16
- properties['max-files'].to_i <= f.object.send(@model.get_image_relationship).count.to_i
16
+ properties['max-files'].to_i <= f.object.send(@model.gallery_relationship).count.to_i
17
17
  ) %>
18
18
  <% hidden = 'hidden' %>
19
19
  <% else %>
@@ -15,27 +15,55 @@
15
15
  <table id="<%= table_type(@model) %>" class="table table-striped table-bordered dataTable">
16
16
  <thead><!-- model attributes -->
17
17
  <tr>
18
+ <% if @model.is_sortable? %>
19
+ <th></th>
20
+ <% end %>
18
21
  <% @model.display_attributes('index').each do |fields| %>
19
22
  <% fields.each do |attribute, properties| %>
20
23
  <th><%= properties['label'] %></th>
21
24
  <% end %>
22
25
  <% end %>
23
- <% if @model.is_sortable? %>
24
- <th>
25
- <%= I18n.t('position') %>
26
- </th>
27
- <% end %>
28
26
  <th><%= I18n.t('actions') %></th>
29
27
  </tr>
30
28
  </thead><!-- Ends model attributes -->
31
- <% if @collection != [] %>
32
- <% last_update = @collection.max_by(&:updated_at).updated_at %>
33
- <% end %>
34
- <% cache ["#{@model.name}-collection", last_update], skip_digest: true do %>
35
- <tbody id="body-content">
36
- <%= render 'adminpanel/shared/index_records', collection: @collection %>
37
- </tbody>
38
- <% end %><!-- end collection cache -->
29
+
30
+ <tbody id="<%= table_type(@model) %>">
31
+ <% @collection = @collection.ordered if table_type(@model) == 'sortable' %>
32
+ <% @collection.each do |member| %>
33
+ <% cache ["#{member.class}-member", member] do %>
34
+ <tr
35
+ data-id="<%= member.id %>"
36
+ <% if @model.is_sortable? %>
37
+ data-url="<%= url_for [:move_to_position, member] %>"
38
+ <% end %>
39
+ >
40
+ <% if @model.is_sortable? %>
41
+ <td class="draggable">
42
+ <i class="fa fa-bars"></i>
43
+ </td>
44
+ <% end %>
45
+ <% @model.display_attributes('index').each do |fields| %>
46
+ <% fields.each do |attribute, properties| %>
47
+ <td>
48
+ <%= field_value(properties, attribute, member) %>
49
+ </td>
50
+ <% end %>
51
+ <% end %>
52
+ <td>
53
+ <%= render 'adminpanel/icons/show', resource: member %>
54
+
55
+ <%= render 'adminpanel/icons/edit', resource: member %>
56
+
57
+ <%= render 'adminpanel/icons/delete', resource: member %>
58
+
59
+ <%= render 'adminpanel/icons/facebook', resource: member %>
60
+
61
+ <%= render 'adminpanel/icons/twitter', resource: member %>
62
+ </td>
63
+ </tr>
64
+ <% end %>
65
+ <% end %>
66
+ </tbody>
39
67
  </table>
40
68
  </div>
41
69
  </div>
@@ -44,32 +44,52 @@
44
44
  </div>
45
45
  </div>
46
46
 
47
- <% if @model.has_images? %>
47
+ <% if @model.has_gallery? %>
48
48
  <div class="widget widget-padding span6">
49
49
  <div class="widget-header">
50
50
  <%= content_tag(:i, nil, class: "fa fa-#{@model.icon}") %>
51
51
  <h5><%= I18n.t('gallery.container') %>: <%= @model.display_name.humanize %>
52
- <%= render 'adminpanel/icons/edit', resource: @resource_instance %>
52
+ <%= render 'adminpanel/icons/edit', resource: @resource_instance %>
53
53
  </h5>
54
54
  </div>
55
- <% if @model.gallery_children %>
55
+ <% if @model.has_sortable_gallery? %>
56
56
  <div class="widget-body widget-tasks-assigned clearfix">
57
- <ul id="gallery-entries">
58
- <%= render(
59
- 'adminpanel/shared/gallery_entries',
60
- images: @resource_instance.send(
61
- @model.get_image_relationship
62
- ).ordered
63
- ) %>
64
- </ul>
57
+ <table class="table table-striped table-bordered">
58
+ <thead>
59
+ <tr>
60
+ <td class="draggable-header"></td>
61
+ <td><i class="fa fa-picture-o"></i></td>
62
+ </tr>
63
+ </thead>
64
+ <tbody id="sortable">
65
+ <% collection = @resource_instance.send(@model.gallery_relationship).ordered %>
66
+ <% collection.each do |image| %>
67
+ <tr
68
+ data-id="<%= image.id %>"
69
+ data-url="<%= url_for [:move_to_position, image] %>"
70
+ >
71
+ <td class="draggable img"><i class="fa fa-bars fa-2x"></i></td>
72
+ <td>
73
+ <%= link_to(
74
+ image_tag(image.file_url(:thumb)),
75
+ image.file.to_s,
76
+ rel: "group",
77
+ name: @model.display_name
78
+ ) %>
79
+ </td>
80
+ </tr>
81
+ <% end %>
82
+ </tbody>
83
+ </table>
65
84
  </div>
66
85
  <% else %>
67
86
  <div class="widget-body row-fluid">
68
- <% @resource_instance.send(@model.get_image_relationship).each do |image|%>
87
+ <% @resource_instance.send(@model.gallery_relationship).each do |image|%>
69
88
  <%= link_to(
70
89
  image_tag( image.file_url(:thumb) ),
71
90
  image.file_url.to_s,
72
- rel: 'group', name: @model.display_name
91
+ rel: 'group',
92
+ name: @model.display_name
73
93
  ) %>
74
94
  <% end %>
75
95
  </div>