adminpanel 2.4.3 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/README.md +16 -16
- data/adminpanel.gemspec +9 -8
- data/app/assets/javascripts/adminpanel/application.js +4 -0
- data/app/assets/javascripts/adminpanel/bootstrap-wysihtml5.js +2 -4
- data/app/assets/javascripts/adminpanel/sortable.js.coffee +27 -0
- data/app/assets/stylesheets/adminpanel/application.css +1 -0
- data/app/assets/stylesheets/adminpanel/sortable.css.scss.erb +13 -0
- data/app/controllers/adminpanel/application_controller.rb +0 -1
- data/app/controllers/adminpanel/sessions_controller.rb +5 -2
- data/app/controllers/concerns/adminpanel/rest_actions.rb +24 -22
- data/app/controllers/concerns/adminpanel/sortable_actions.rb +3 -20
- data/app/helpers/adminpanel/breadcrumbs_helper.rb +6 -5
- data/app/helpers/adminpanel/router_helper.rb +9 -3
- data/app/helpers/adminpanel/shared_pages_helper.rb +1 -1
- data/app/models/concerns/adminpanel/base.rb +34 -11
- data/app/models/concerns/adminpanel/sitemap.rb +0 -1
- data/app/models/concerns/adminpanel/sortable.rb +33 -30
- data/app/models/concerns/adminpanel/sortable_gallery.rb +90 -0
- data/app/views/adminpanel/form/_adminpanel_file_field.html.erb +1 -1
- data/app/views/adminpanel/templates/index.html.erb +41 -13
- data/app/views/adminpanel/templates/show.html.erb +33 -13
- data/config/initializers/adminpanel/carrierwave_mini_magick_quality.rb +11 -0
- data/config/locales/en.yml +3 -7
- data/config/locales/es.yml +1 -8
- data/config/routes.rb +6 -8
- data/lib/adminpanel.rb +9 -8
- data/lib/adminpanel/version.rb +1 -1
- data/lib/generators/adminpanel/custom_errors/custom_errors_generator.rb +37 -0
- data/lib/generators/adminpanel/custom_errors/templates/errors_controller.rb +14 -0
- data/lib/generators/adminpanel/custom_errors/templates/show.html.erb +1 -0
- data/lib/generators/adminpanel/gallery/templates/gallery_template.rb +8 -3
- data/lib/generators/adminpanel/gallery/templates/uploader.rb +4 -1
- data/lib/generators/adminpanel/initialize/initialize_generator.rb +0 -12
- data/lib/generators/adminpanel/initialize/templates/adminpanel_setup.rb +1 -2
- data/lib/generators/adminpanel/resource/resource_generator.rb +29 -8
- data/lib/generators/adminpanel/resource/resource_generator_helper.rb +34 -7
- data/lib/generators/adminpanel/resource/templates/adminpanel_resource_template.rb +7 -2
- data/lib/tasks/adminpanel/adminpanel.rake +19 -61
- data/test/dummy/app/models/adminpanel/file_resourcefile.rb +1 -1
- data/test/dummy/app/models/adminpanel/gallery.rb +9 -4
- data/test/dummy/app/models/adminpanel/galleryfile.rb +2 -2
- data/test/dummy/app/models/adminpanel/photo.rb +1 -1
- data/test/dummy/app/models/adminpanel/product.rb +0 -4
- data/test/dummy/config/initializers/adminpanel_setup.rb +1 -1
- data/test/dummy/test/fixtures/adminpanel/galleryfiles.yml +24 -0
- data/test/features/shared/concerns/sortable_gallery_ui_test.rb +25 -0
- data/test/features/shared/concerns/sortable_test.rb +4 -4
- data/test/features/shared/form/{belongs_to_non_category_modal_test.rb → belongs_to_remote_test.rb} +1 -1
- data/test/features/shared/form/{has_many_through_non_category_modal_test.rb → has_many_through_remote_test.rb} +1 -1
- data/test/generators/dump_generator_test.rb +1 -13
- data/test/generators/gallery_generator_test.rb +1 -1
- data/test/generators/initialize_generator_test.rb +1 -9
- data/test/generators/resource_generator_test.rb +21 -1
- data/test/helpers/router_helper_test.rb +0 -4
- data/test/models/adminpanel/sortable_gallery_unit_test.rb +118 -0
- data/test/models/adminpanel/sortable_unit_test.rb +75 -0
- data/test/tasks/adminpanel_rake_test.rb +1 -1
- metadata +86 -85
- data/app/assets/images/adminpanel/loguito.png +0 -0
- data/app/controllers/adminpanel/categories_controller.rb +0 -52
- data/app/controllers/concerns/adminpanel/galleryzable_actions.rb +0 -34
- data/app/models/concerns/adminpanel/galleryzation.rb +0 -78
- data/app/views/adminpanel/categories/_categories_table.html.erb +0 -48
- data/app/views/adminpanel/categories/_category_form.html.erb +0 -33
- data/app/views/adminpanel/categories/create.js.erb +0 -6
- data/app/views/adminpanel/categories/index.html.erb +0 -63
- data/app/views/adminpanel/categories/new.js.erb +0 -5
- data/app/views/adminpanel/icons/_move_to_better.html.erb +0 -17
- data/app/views/adminpanel/icons/_move_to_worst.html.erb +0 -18
- data/app/views/adminpanel/shared/_gallery_entries.html.erb +0 -11
- data/app/views/adminpanel/shared/_index_records.html.erb +0 -32
- data/app/views/adminpanel/templates/gallery_entries.js.erb +0 -1
- data/app/views/adminpanel/templates/index_records.js.erb +0 -1
- data/lib/generators/adminpanel/initialize/templates/category_template.rb +0 -45
- data/lib/generators/adminpanel/initialize/templates/create_adminpanel_categories_table.rb +0 -11
- data/test/features/categories/categories_index_test.rb +0 -31
- data/test/features/shared/concerns/galleryzable_test.rb +0 -22
- data/test/features/shared/form/belongs_to_category_modal_test.rb +0 -35
- data/test/features/shared/form/has_many_through_category_modal_test.rb +0 -35
- data/test/models/adminpanel/galleryzable_test.rb +0 -28
@@ -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
|
-
|
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
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
self.decrement!(:position)
|
16
|
+
def ordered
|
17
|
+
order('position ASC')
|
18
|
+
end
|
25
19
|
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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.
|
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',
|
52
|
+
<%= render 'adminpanel/icons/edit', resource: @resource_instance %>
|
53
53
|
</h5>
|
54
54
|
</div>
|
55
|
-
<% if @model.
|
55
|
+
<% if @model.has_sortable_gallery? %>
|
56
56
|
<div class="widget-body widget-tasks-assigned clearfix">
|
57
|
-
<
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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.
|
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',
|
91
|
+
rel: 'group',
|
92
|
+
name: @model.display_name
|
73
93
|
) %>
|
74
94
|
<% end %>
|
75
95
|
</div>
|