caboose-cms 0.5.151 → 0.5.152

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZDg5YjIzMDA3ZDMwMjhhMTQxMDRmYTMwNDkwNjIxNTQzYzljMzk3ZA==
4
+ NTZhNjlmYTMzZjhhNmZmM2RiMzM1YzI4Mzg5NGU5OTkxZWYxZDkwZg==
5
5
  data.tar.gz: !binary |-
6
- ZDVmY2Q0OTE3OTI0ODJiYzI3ZGJkNTAyMWRlODhkMzZkOGQwNjhmMA==
6
+ NzBhZTUzN2Y5NTMzNTVjYzY0MDdkNThlOGU5NzIyNGE3MmUzNTJhNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZDA4ZGE4Y2VkZGY5NjE5OGYyMTk1YWFhN2E4OGFhYjhlYzE3MzZlMzMxYzEy
10
- MzFlNjg2OTczODViYzRjMGEzMjVlYTgxNzU0YmVmYWY3MmUxZjY4ZmFhOTI3
11
- NDYzMDAwZGYyOWNlN2E1MDY2Y2YzNmEwNmU4NmM1ZjAzODg4YjQ=
9
+ ZGNhMmJlZjIzNmJjOTI4OTQ4MTU3MDdiZjNlMWEzNTFkZjU4NGUyMmM2MWU1
10
+ Njc0NmI1NWMxNmE5MmMzNjhkMTQyZjY1MmZlZjQwZTJlYjc4NjU0OTI2ODIy
11
+ MDI4YzVjMGM5NWQ2MTkwZjExZDdkNDZiNTk5YTJlYjA3Yjk4YTY=
12
12
  data.tar.gz: !binary |-
13
- NjY4M2E4NzgxY2UzYmQ4YmIzY2JkNmU1NGQ0MGY2NDNkYzYxMjZlMWQxYWM2
14
- NGY2ZjliY2E0YWFmMGMwN2Y5NzkyNGI3ZjQ3YWEyN2YyZjNhZjhhYjM5NGE0
15
- ZGVmNWUzZDg5MTc0MzI3OTliY2IxZWM1YWQ4Yjg1ZWU2ZGEwZTc=
13
+ OWUyM2EyNWU1ZDc3Njg4YWM3ZmMxMTMzOTE3ZWI1YzIwYmUxNDhhOWQ3ZDg4
14
+ ZTVhNTQ3NjQwZDM5YTZhNzM1MGVlNjYxNTFiMDEyZDA1NzY5MWJkMTA0ZTE3
15
+ MDNlZTNkYjE5ODNhNTViNTEwNjgzYmRhNDBlYzBiN2U3Y2I0NzE=
@@ -134,6 +134,18 @@ module Caboose
134
134
  admin_options_helper(c, "#{prefix} - ")
135
135
  end
136
136
  end
137
+
138
+ # GET /admin/categories/:category_id/products/json
139
+ def admin_category_products
140
+ query = ["select P.id, P.title from store_category_memberships CM
141
+ left join store_products P on P.id = CM.product_id
142
+ where CM.category_id = ?
143
+ order by CM.sort_order, P.title", params[:id]]
144
+ rows = ActiveRecord::Base.connection.select_rows(ActiveRecord::Base.send(:sanitize_sql_array, query))
145
+ arr = rows.collect{ |row| { :id => row[0], :title => row[1] }}
146
+ render :json => arr
147
+ end
148
+
137
149
  end
138
150
  end
139
151
 
@@ -74,12 +74,13 @@ module Caboose
74
74
  'price_gte' => '',
75
75
  'price_lte' => '',
76
76
  'alternate_id' => '',
77
- 'search_like' => ''
78
- #'pcs_category_id' => cat.id
77
+ 'search_like' => '',
78
+ 'cm_category_id' => cat.id # This filters the CategoryMembership object that we'll be sorting on
79
79
  }, {
80
80
  'model' => 'Caboose::Product',
81
- 'sort' => if params[:sort] then params[:sort] else 'store_products.sort_order' end,
82
- #'sort' => if params[:sort] then params[:sort] else 'store_product_category_sorts.sort_order' end,
81
+ #'sort' => if params[:sort] then params[:sort] else 'store_products.sort_order' end,
82
+ #'sort' => if params[:sort] then params[:sort] else 'store_category_memberships.sort_order' end,
83
+ 'sort' => 'store_category_memberships.sort_order',
83
84
  'base_url' => url_without_params,
84
85
  'items_per_page' => 15,
85
86
  'use_url_params' => false,
@@ -89,15 +90,15 @@ module Caboose
89
90
  },
90
91
 
91
92
  'includes' => {
92
- #'pcs_category_id' => [ 'product_category_sorts', 'category_id' ],
93
- 'category_id' => [ 'categories' , 'id' ],
94
- 'category_name' => [ 'categories' , 'name' ],
95
- 'vendor_id' => [ 'vendor' , 'id' ],
96
- 'vendor_name' => [ 'vendor' , 'name' ],
97
- 'vendor_status' => [ 'vendor' , 'status' ],
98
- 'price_gte' => [ 'variants' , 'price' ],
99
- 'price_lte' => [ 'variants' , 'price' ],
100
- 'variant_status' => [ 'variants' , 'status' ]
93
+ 'cm_category_id' => [ 'category_memberships' , 'category_id' ],
94
+ 'category_id' => [ 'categories' , 'id' ],
95
+ 'category_name' => [ 'categories' , 'name' ],
96
+ 'vendor_id' => [ 'vendor' , 'id' ],
97
+ 'vendor_name' => [ 'vendor' , 'name' ],
98
+ 'vendor_status' => [ 'vendor' , 'status' ],
99
+ 'price_gte' => [ 'variants' , 'price' ],
100
+ 'price_lte' => [ 'variants' , 'price' ],
101
+ 'variant_status' => [ 'variants' , 'status' ]
101
102
  }
102
103
  })
103
104
 
@@ -467,17 +468,19 @@ module Caboose
467
468
 
468
469
  # GET /admin/products/sort
469
470
  def admin_sort
470
- @products = Product.active
471
- @vendors = Vendor.active
472
- @categories = Category.all
473
-
471
+ #@products = Product.active
472
+ #@vendors = Vendor.active
473
+ #@categories = Category.all
474
474
  render :layout => 'caboose/admin'
475
475
  end
476
476
 
477
- # PUT /admin/products/update-sort-order
477
+ # PUT /admin/categories/:category_id/products/sort-order
478
478
  def admin_update_sort_order
479
- params[:product_ids].each_with_index do |product_id, index|
480
- Product.find(product_id.to_i).update_attribute(:sort_order, index)
479
+ cat_id = params[:category_id]
480
+ params[:product_ids].each_with_index do |product_id, i|
481
+ cm = CategoryMembership.where(:category_id => cat_id, :product_id => product_id).first
482
+ cm.sort_order = i
483
+ cm.save
481
484
  end
482
485
  render :json => { :success => true }
483
486
  end
@@ -69,8 +69,7 @@ class Caboose::Schema < Caboose::Utilities::Schema
69
69
  :shipping_carrier ,
70
70
  :shipping_service_code ,
71
71
  :shipping_service_name ,
72
- :transaction_id ,
73
- :transaction_id ,
72
+ :transaction_id ,
74
73
  :transaction_service ,
75
74
  :amount_discounted ,
76
75
  :auth_code ,
@@ -248,7 +247,8 @@ class Caboose::Schema < Caboose::Utilities::Schema
248
247
  ],
249
248
  Caboose::CategoryMembership => [
250
249
  [ :category_id , :integer ],
251
- [ :product_id , :integer ]
250
+ [ :product_id , :integer ],
251
+ [ :sort_order , :integer , { :default => 0 }]
252
252
  ],
253
253
  Caboose::CustomizationMembership => [
254
254
  [ :product_id , :integer ],
@@ -483,12 +483,7 @@ class Caboose::Schema < Caboose::Utilities::Schema
483
483
  [ :on_sale , :boolean , { :default => false }],
484
484
  [ :allow_gift_wrap , :boolean , { :default => false }],
485
485
  [ :gift_wrap_price , :decimal , { :precision => 8, :scale => 2 }]
486
- ],
487
- Caboose::ProductCategorySort => [
488
- [ :product_id , :integer ],
489
- [ :category_id , :integer ],
490
- [ :sort_order , :integer ]
491
- ],
486
+ ],
492
487
  Caboose::ProductImage => [
493
488
  [ :product_id , :integer ],
494
489
  [ :alternate_id , :string ],
@@ -1,250 +1,88 @@
1
1
  <h1>Sort Products</h1>
2
2
 
3
- <section>
4
- <aside>
5
- <ul id="source" class="sortable">
6
- <% @products.each do |product| %>
7
- <li data-id="<%= product.id %>"><%= product.title %></li>
8
- <% end %>
9
- </ul>
10
-
11
- <input name="search" type="search" placeholder="Search for Products" />
12
-
13
- <select class="filter" name="vendor">
14
- <option value="">-- Filter by Vendor --</option>
15
- <% @vendors.each do |vendor| %>
16
- <option value="<%= vendor.id %>"><%= vendor.name %></option>
17
- <% end %>
18
- </select>
19
- </aside>
20
-
21
- <article>
22
- <ul id="target" class="sortable">
23
- <% @products.each do |product| %>
24
- <li data-id="<%= product.id %>"><%= product.title %></li>
25
- <% end %>
26
- </ul>
27
-
28
- <input id="submit" type="button" value="Apply" /><br />
29
- </article>
30
- </section>
3
+ <p><select id="category_id">
4
+ <option value="">-- Select a category --</option>
5
+ <% Caboose::Category.options(@site.id).each do |cat| %>
6
+ <option value='<%= cat[:value] %>'><%= cat[:text] %></option>
7
+ <% end %>
8
+ </select></p>
9
+ <div id='products'></div>
10
+ <div id='message'></div>
31
11
 
32
12
  <% content_for :caboose_js do %>
33
- <%= javascript_include_tag('underscore') %>
34
13
  <script type='text/javascript'>
35
- window.products = <%= @products.to_json.html_safe %>;
36
- window.results = window.products; // Used to store filtered results
37
-
38
- // Delay method
39
- var delay = (function(){
40
- var timer = 0;
41
- return function(callback, ms){
42
- clearTimeout (timer);
43
- timer = setTimeout(callback, ms);
44
- };
45
- })();
46
-
47
- // Filter
48
- function filter(event) {
49
- var $source = $('ul#source')
50
- , $search = $('input[name=search]')
51
- , search_string = $search.val() === $search.attr('placeholder') ? undefined : $search.val().trim().toUpperCase()
52
- , vendor_id = $('select[name=vendor]').val();
53
-
54
- $source.empty();
55
-
56
- _.each(window.products, function(product) {
57
- if (!search_string && !vendor_id
58
- || search_string && product.title.toUpperCase().indexOf(search_string) > -1
59
- || vendor_id && product.vendor_id == vendor_id) {
60
- $source.append( $('<li/>').attr('data-id', product.id).text(product.title) );
61
- }
14
+
15
+ $(document).ready(function() {
16
+ $('#category_id').change(function() {
17
+ update_products();
62
18
  });
63
- }
19
+ update_products();
20
+ });
64
21
 
65
- function update(event) {
22
+ function update_products()
23
+ {
24
+ var cat_id = $('#category_id').val();
25
+ if (cat_id == '')
26
+ {
27
+ $('#message').empty().html("<p class'note error'>Please select a category.</p>");
28
+ return;
29
+ }
66
30
 
67
- // Send the ordered array to the server to make it official
31
+ $('#message').empty().html("<p class'loading'>Getting products...</p>");
68
32
  $.ajax({
69
- type: 'put',
70
- url: '/admin/products/update-sort-order',
71
- data: { product_ids: $('ul#target').sortable('toArray', { attribute: 'data-id' }) }
72
- });
33
+ url: '/admin/categories/' + cat_id + '/products/json',
34
+ type: 'get',
35
+ success: function(products) {
36
+ var ul = $('<ul/>').attr('id', 'product_list');
37
+ $.each(products, function(i, p) {
38
+ ul.append($('<li/>').attr('id', 'product_' + p.id).data('id', p.id).html(p.title));
39
+ });
40
+ $('#message').empty();
41
+ $('#products').empty().append(ul);
42
+ $('#product_list').sortable({
43
+ stop: function(event, ui)
44
+ {
45
+ $.ajax({
46
+ url: '/admin/categories/' + $('#category_id').val() + '/products/sort-order',
47
+ type: 'put',
48
+ data: {
49
+ product_ids: $.map($('#product_list').sortable('toArray'), function(str, j) { return parseInt(str.replace('product_', '')); })
50
+ }
51
+ });
52
+ }
53
+ });
54
+ }
55
+ });
73
56
  }
74
57
 
75
- $(document).ready(function() {
76
- var selected_class = 'selected';
77
-
78
- // Selection rules
79
- $('ul.sortable').on('click', 'li', function(event) {
80
- $element = $(this);
81
-
82
- if (event.shiftKey && $last_element) {
83
- if ($element.index() < $last_element.index()) {
84
- $element.nextUntil($last_element).addClass(selected_class);
85
- } else {
86
- $element.prevUntil($last_element).addClass(selected_class);
87
- }
88
-
89
- $element.toggleClass(selected_class);
90
- } else if (event.ctrlKey || event.metaKey) {
91
- if ($element.hasClass(selected_class)) {
92
- $element.removeClass(selected_class);
93
- } else {
94
- $element.addClass(selected_class);
95
- }
96
- } else {
97
- $element.addClass(selected_class).siblings().removeClass(selected_class);
98
- }
99
-
100
- $last_element = $element;
101
- });
102
-
103
- // Setup sortable lists
104
- $('ul#source').sortable({
105
- delay: 150,
106
- revert: 0,
107
- connectWith: 'ul#target',
108
-
109
- helper: function(event, item) {
110
-
111
- // If the user just clicked and immediately drug an element
112
- if ( !item.hasClass(selected_class) ) item.addClass(selected_class).siblings().removeClass(selected_class);
113
-
114
- // Grab the selected elements and create the helper
115
- var elements = item.parent().children('.' + selected_class).clone()
116
- , helper = $('<li/>');
117
-
118
- // Add the elements to the item multidrag data attribute
119
- item.data('multidrag', elements).siblings('.' + selected_class);
120
-
121
- // Pass back the helper
122
- return helper.append(elements);
123
- },
124
-
125
- start: function(event, ui) {
126
-
127
- // Make sure the item stays visible on #source
128
- $(ui.item).show();
129
-
130
- // Clone the original item and note the previous one, to reappend after jquery ui takes it away
131
- item_clone = $(ui.item).clone();
132
- previous_item = $(ui.item).prev();
133
-
134
- // Remove selected status from ul#target
135
- $('ul#target li.selected').removeClass('selected');
136
- },
137
-
138
- beforeStop: function(event, ui) {
139
-
140
- if ($(ui.item).parent().attr('id') != 'source') {
141
-
142
- // Remove duplicate items from old positions
143
- ui.item.data('multidrag').each(function(index, element) {
144
- var $element = $(element);
145
- $('ul#target li[data-id=' + $element.attr('data-id') + ']').not('.selected').remove()
146
- });
147
- }
148
- },
149
-
150
- stop: function(event, ui) {
151
-
152
- if ($(ui.item).parent().attr('id') == 'source') return false;
153
-
154
- // Clear multidrag data
155
- ui.item.after( ui.item.data('multidrag') ).remove();
156
-
157
- // If the previous item is defined append the clone just after, otherwise prepend to #source
158
- if (previous_item.length) {
159
- previous_item.after(item_clone);
160
- } else {
161
- $('ul#source').prepend(item_clone);
162
- }
163
-
164
- // Update sort order
165
- update(event, ui);
166
- }
167
- });
168
-
169
- // Update sort order when done sorting
170
- $('ul#target').sortable({ stop: update });
171
-
172
- // Filter when the vendor select box change
173
- $('select').on('change', filter);
174
-
175
- // Filter, after a delay, when there is a keyup event in the search
176
- $('input[type=search]').on('keyup', function(event) {
177
- delay(function() { filter(event) }, 600);
178
- });
179
- });
180
58
  </script>
181
59
  <% end %>
182
60
 
183
61
  <% content_for :caboose_css do %>
184
- <style>
185
-
186
- /* Layout */
187
-
188
- section,
189
- section article { overflow: hidden; }
190
-
191
- section aside {
192
- float: left;
193
- margin-right: 12px;
194
- }
195
-
196
- /* Filters */
197
-
198
- input[type=search], select {
199
- box-sizing: border-box;
200
- margin: 6px 0;
201
- width: 350px;
202
- outline: none !important;
203
- }
204
- input[type=search] { height: 42px; }
205
- select { display: block; }
206
-
207
- input[type=button] {
208
- background: #ccc;
209
- cursor: pointer;
210
- margin: 12px 0;
211
- padding: 6px;
212
- outline: none !important;
213
- }
214
-
215
- /* Lists */
216
-
217
- ul.sortable {
218
- border: 1px solid #ccc;
219
- height: 250px;
220
- list-style: none;
221
- margin: 0;
222
- overflow-x: hidden;
223
- overflow-y: scroll;
224
- padding: 0;
225
- width: 350px;
226
- -webkit-touch-callout: none;
227
- -webkit-user-select: none;
228
- -khtml-user-select: none;
229
- -moz-user-select: none;
230
- -ms-user-select: none;
231
- user-select: none;
232
- }
233
- ul.sortable li {
234
- box-sizing: border-box;
235
- border-bottom: 1px solid #ccc;
236
- cursor: pointer;
237
- cursor: grab;
238
- display: block;
239
- padding: 6px;
240
- width: 100%;
241
- }
242
- ul.sortable li.selected {
243
- background: #3e9aff;
244
- border-color: #fff;
245
- color: #fff;
246
- }
62
+ <style>
63
+
64
+ #product_list {
65
+ list-style: none;
66
+ margin: 0;
67
+ padding: 0;
68
+ width: 350px;
69
+ }
70
+ #product_list li {
71
+ box-sizing: border-box;
72
+ border-top: 1px solid #ccc;
73
+ border-bottom: 1px solid #ccc;
74
+ cursor: pointer;
75
+ cursor: grab;
76
+ display: block;
77
+ padding: 6px;
78
+ width: 100%;
79
+ }
80
+
81
+ #product_list li.selected {
82
+ background: #3e9aff;
83
+ border-color: #fff;
84
+ color: #fff;
85
+ }
247
86
 
248
- ul#source .ui-sortable-placeholder { display: none; }
249
- </style>
250
- <% end %>
87
+ </style>
88
+ <% end %>
@@ -413,14 +413,14 @@ Caboose::Engine.routes.draw do
413
413
 
414
414
  get "/admin/products" => "products#admin_index"
415
415
  get "/admin/products/json" => "products#admin_json"
416
- get '/admin/products/sort' => 'products#admin_sort'
417
- put '/admin/products/update-sort-order' => 'products#admin_update_sort_order'
416
+ get '/admin/products/sort' => 'products#admin_sort'
417
+ put "/admin/categories/:category_id/products/sort-order" => "products#admin_update_sort_order"
418
418
  put "/admin/products/update-vendor-status/:id" => "products#admin_update_vendor_status"
419
419
  get "/admin/products/new" => "products#admin_new"
420
420
  get "/admin/products/status-options" => "products#admin_status_options"
421
421
  get "/admin/products/:id/general" => "products#admin_edit_general"
422
422
  get "/admin/products/:id/description" => "products#admin_edit_description"
423
- get "/admin/products/:id/categories" => "products#admin_edit_categories"
423
+ get "/admin/products/:id/categories" => "products#admin_edit_categories"
424
424
  post "/admin/products/:id/categories" => "products#admin_add_to_category"
425
425
  delete "/admin/products/:id/categories/:category_id" => "products#admin_remove_from_category"
426
426
 
@@ -480,16 +480,17 @@ Caboose::Engine.routes.draw do
480
480
  #=============================================================================
481
481
  # Categories
482
482
  #=============================================================================
483
-
484
- get "/admin/categories" => "categories#admin_index"
485
- get "/admin/categories/new" => "categories#admin_new"
486
- get "/admin/categories/options" => "categories#admin_options"
487
- get '/admin/categories/status-options' => 'categories#admin_status_options'
488
- get "/admin/categories/:id" => "categories#admin_edit"
489
- put "/admin/categories/:id" => "categories#admin_update"
490
- post "/admin/categories/:id" => "categories#admin_update"
491
- post "/admin/categories" => "categories#admin_add"
492
- delete "/admin/categories/:id" => "categories#admin_delete"
483
+
484
+ get "/admin/categories" => "categories#admin_index"
485
+ get "/admin/categories/new" => "categories#admin_new"
486
+ get "/admin/categories/options" => "categories#admin_options"
487
+ get '/admin/categories/status-options' => 'categories#admin_status_options'
488
+ get "/admin/categories/:id/products/json" => "categories#admin_category_products"
489
+ get "/admin/categories/:id" => "categories#admin_edit"
490
+ put "/admin/categories/:id" => "categories#admin_update"
491
+ post "/admin/categories/:id" => "categories#admin_update"
492
+ post "/admin/categories" => "categories#admin_add"
493
+ delete "/admin/categories/:id" => "categories#admin_delete"
493
494
 
494
495
  #=============================================================================
495
496
  # Orders
@@ -1,3 +1,3 @@
1
1
  module Caboose
2
- VERSION = '0.5.151'
2
+ VERSION = '0.5.152'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caboose-cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.151
4
+ version: 0.5.152
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Barry