caboose-cms 0.5.151 → 0.5.152

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 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