spree_favorite_products 3.0.0 → 3.2.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +1 -1
  4. data/Gemfile +10 -11
  5. data/README.md +8 -25
  6. data/Rakefile +1 -2
  7. data/app/assets/javascripts/spree/backend/spree_favorite_products.js +0 -0
  8. data/app/assets/javascripts/spree/frontend/spree_favorite_products.js +23 -0
  9. data/app/assets/stylesheets/spree/backend/spree_favorite_products.css +0 -0
  10. data/app/assets/stylesheets/spree/frontend/spree_favorite_products.css +0 -0
  11. data/app/controllers/spree/admin/favorite_products_controller.rb +14 -5
  12. data/app/controllers/spree/admin/products_controller_decorator.rb +6 -0
  13. data/app/controllers/spree/admin/users_controller_decorator.rb +5 -0
  14. data/app/controllers/spree/favorite_products_controller.rb +14 -6
  15. data/app/models/spree/app_configuration_decorator.rb +2 -1
  16. data/app/models/spree/favorite.rb +9 -6
  17. data/app/models/spree/product_decorator.rb +6 -10
  18. data/app/models/spree/user_decorator.rb +5 -5
  19. data/app/overrides/add_favorite_products_per_page_configuration.rb +5 -5
  20. data/app/overrides/add_favorite_products_to_products_tab.rb +4 -4
  21. data/app/overrides/add_favorite_users_tab_to_products.rb +10 -0
  22. data/app/overrides/add_link_to_mark_product_as_favorite.rb +8 -7
  23. data/app/overrides/add_link_to_users_favorite_products.rb +5 -5
  24. data/app/overrides/addd_favorite_products_tab_to_users.rb +10 -0
  25. data/app/views/spree/admin/favorite_products/_users.html.erb +25 -0
  26. data/app/views/spree/admin/favorite_products/index.html.erb +9 -16
  27. data/app/views/spree/admin/products/favorite_users.html.erb +14 -0
  28. data/app/views/spree/admin/users/favorite_products.html.erb +50 -0
  29. data/app/views/spree/favorite_products/destroy.js.erb +1 -1
  30. data/app/views/spree/favorite_products/index.html.erb +6 -6
  31. data/config/locales/bg.yml +13 -0
  32. data/config/locales/en.yml +21 -3
  33. data/config/locales/pl.yml +19 -0
  34. data/config/routes.rb +11 -3
  35. data/db/migrate/20130705080641_create_table_favorites.rb +1 -1
  36. data/db/migrate/20130710105100_rename_favorites_to_spree_favorites.rb +1 -1
  37. data/db/migrate/20160304152800_add_favorites_user_counts_to_product.rb +6 -0
  38. data/lib/generators/spree_favorite_products/install/install_generator.rb +4 -3
  39. data/spec/controllers/spree/admin/favorite_products_controller_spec.rb +31 -41
  40. data/spec/controllers/spree/admin/products_controller_decorator_spec.rb +28 -0
  41. data/spec/controllers/spree/admin/users_controller_decorator_spec.rb +28 -0
  42. data/spec/controllers/spree/favorite_products_controller_spec.rb +25 -33
  43. data/spec/models/spree/app_configuration_decorator_spec.rb +2 -2
  44. data/spec/models/spree/favorite_spec.rb +21 -19
  45. data/spec/models/spree/product_decorator_spec.rb +16 -16
  46. data/spec/models/spree/user_decorator_spec.rb +9 -8
  47. data/spec/spec_helper.rb +21 -0
  48. data/spree_favorite_products.gemspec +9 -5
  49. metadata +80 -7
  50. data/Gemfile.lock +0 -345
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f11f3c8880f83651bdb24fe9c818946085b4d8d0
4
- data.tar.gz: 6628a06e36d08be97e9c6fd6b567b8f9228c1a78
3
+ metadata.gz: 4c1b87a8f8374a8725e42a237cd480c073b4b6de
4
+ data.tar.gz: 737eac610412ab5534ec669d222f95ea3e1378d8
5
5
  SHA512:
6
- metadata.gz: 6fe013be6540e9c4797b8a71ec3f0c87d8f52841a8cfe18639a380bc4cd7e1b6d99cebd41730d1a16ff3910339d99b516a6213747a4220b56f2add2040803a09
7
- data.tar.gz: 0d72ec7b52bb628f6b0e67fc056da1c79b610c90264257f4a129a448f48572dbb1aa87e1e6bcf2ee85ac3fd5119440cbd6def1350de2def05fd884e2f87afe24
6
+ metadata.gz: ed5fc3f665c0d97711605b053c5577ada2c60a36b962181d3298af38122054e4d04d09fa12a77124ce85087fa612f6864e985b2b73606f9bced90f2aacace407
7
+ data.tar.gz: bdb7d0aa97295a80e25969276eab56aef30bae46d94f20a42ae44b75d47ddc4278083c07c74bbf276ba0a669fa3a98722eecc6a9bec5a1962882e5238c7a0ac7
data/.gitignore CHANGED
@@ -2,3 +2,5 @@
2
2
  /coverage
3
3
  .DS_STORE
4
4
  .ruby-version
5
+ Gemfile.lock
6
+ .byebug_history
data/.rspec CHANGED
@@ -1 +1 @@
1
- --color
1
+ --color
data/Gemfile CHANGED
@@ -1,19 +1,18 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Provides basic authentication functionality for testing parts of your engine
4
- gem 'spree', '~> 3.0.0'
5
- gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '3-0-stable'
6
- gem 'mysql2'
7
- gem 'sass-rails', '~> 5.0'
4
+ gem 'spree', github: 'spree/spree', branch: '3-2-stable'
5
+ gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: 'master'
8
6
 
9
- group :assets do
10
- gem 'coffee-rails', '4.0.1'
11
- end
7
+ gem 'byebug', '~> 9.0.6'
12
8
 
13
9
  group :test do
14
- gem 'rspec-rails', '~> 2.10'
15
- gem 'shoulda-matchers', '2.2.0'
16
- gem 'simplecov', :require => false
17
- gem 'database_cleaner'
10
+ gem 'rspec-rails', '~> 3.5.2'
11
+ gem 'shoulda-matchers', '3.1.1'
12
+ gem 'simplecov', '~> 0.12.0', require: false
13
+ gem 'database_cleaner', '~> 1.5.3'
14
+ gem 'rspec-activemodel-mocks', '~> 1.0.3'
15
+ gem 'rails-controller-testing', '~> 1.0.1'
18
16
  end
17
+
19
18
  gemspec
data/README.md CHANGED
@@ -1,11 +1,11 @@
1
- Spree Favorite Products [![Code Climate](https://codeclimate.com/github/vinsol/spree_favorite_products.png)](https://codeclimate.com/github/vinsol/spree_favorite_products) [![Build Status](https://travis-ci.org/vinsol/spree_favorite_products.png?branch=master)](https://travis-ci.org/vinsol/spree_favorite_products)
2
- =====================
1
+ Spree Favorite Products
2
+ =======================
3
3
 
4
- This extension adds the following features:
4
+ * Spree Favorite Products is an extension that allows the user to mark/unkmark a product as favorite from the product page.
5
5
 
6
- 1. Adds a link 'Mark as favorite' on product detail page.
7
- 2. Favorite Products tab on header
8
- 3. Favorite Products tab in admin section
6
+ * Admin can view which products have been marked as favorite, and by which users, on the Admin end.
7
+
8
+ * It gives user the ability to see all products marked as favorite by him/her.
9
9
 
10
10
  Installation
11
11
  ------------
@@ -13,24 +13,7 @@ Installation
13
13
  Add spree_favorite_products to your Gemfile:
14
14
 
15
15
  ```ruby
16
- gem 'spree_favorite_products', github: 'vinsol/spree_favorite_products', branch: '3-0-stable'
17
- ```
18
-
19
- For older versions of spree.
20
-
21
- ```ruby
22
- # Spree 2.2.x
23
- gem 'spree_favorite_products', '2.2.3'
24
- ```
25
-
26
- ```ruby
27
- # Spree 2.1.x
28
- gem 'spree_favorite_products', '2.0.3'
29
- ```
30
-
31
- ```ruby
32
- # Spree 2.0.x
33
- gem 'spree_favorite_products', '1.0.0'
16
+ gem 'spree_favorite_products'
34
17
  ```
35
18
 
36
19
  Bundle your dependencies and run the installation generator:
@@ -74,4 +57,4 @@ Credits
74
57
 
75
58
  [![vinsol.com: Ruby on Rails, iOS and Android developers](http://vinsol.com/vin_logo.png "Ruby on Rails, iOS and Android developers")](http://vinsol.com)
76
59
 
77
- Copyright (c) 2014 [vinsol.com](http://vinsol.com "Ruby on Rails, iOS and Android developers"), released under the New MIT License
60
+ Copyright (c) 2016 [vinsol.com](http://vinsol.com "Ruby on Rails, iOS and Android developers"), released under the New MIT License
data/Rakefile CHANGED
@@ -6,11 +6,10 @@ require 'spree/testing_support/extension_rake'
6
6
 
7
7
  RSpec::Core::RakeTask.new
8
8
 
9
- task :default => [:spec]
9
+ task default: [:spec]
10
10
 
11
11
  desc 'Generates a dummy app for testing'
12
12
  task :test_app do
13
13
  ENV['LIB_NAME'] = 'spree_favorite_products'
14
- ENV['DB'] = 'mysql'
15
14
  Rake::Task['extension:test_app'].invoke
16
15
  end
@@ -0,0 +1,23 @@
1
+ var getQueryParams = function(queryString) {
2
+ queryString = queryString.split('+').join(' ');
3
+
4
+ var params = {},
5
+ tokens,
6
+ re = /[?&]?([^=]+)=([^&]*)/g;
7
+
8
+ while (tokens = re.exec(queryString)) {
9
+ params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
10
+ }
11
+
12
+ return params;
13
+ }
14
+
15
+ $(document).ready(
16
+ function(){
17
+ var params = getQueryParams(document.location.search);
18
+ if(params['favorite_product_id'] != null){
19
+ $('#mark-as-favorite').attr('data-remote', true);
20
+ $('#mark-as-favorite').trigger('click');
21
+ }
22
+ }
23
+ );
@@ -3,13 +3,22 @@ module Spree
3
3
  class FavoriteProductsController < Spree::Admin::BaseController
4
4
 
5
5
  def index
6
- @search = Spree::Product.favorite.search(params[:q])
6
+ @search = Spree::Product.favorite.includes(master: :images).search(params[:q])
7
7
  @favorite_products = @search.result.order_by_favorite_users_count(sort_in_ascending_users_count?).page(params[:page])
8
8
  end
9
9
 
10
- def users
11
- @product = Spree::Product.where(:id => params[:id]).first
12
- @users = @product.favorite_users.page(params[:page])
10
+ def destroy
11
+ @favorite = Spree::Favorite.find_by(id: params[:id])
12
+ if @favorite.destroy
13
+ flash[:success] = flash_message_for(@favorite, :successfully_removed)
14
+ else
15
+ flash[:error] = @favorite.errors.full_messages.join(', ')
16
+ end
17
+
18
+ respond_with(@favorite) do |format|
19
+ format.html { redirect_to location_after_destroy }
20
+ format.js { render_js_for_destroy }
21
+ end
13
22
  end
14
23
 
15
24
  private
@@ -18,4 +27,4 @@ module Spree
18
27
  end
19
28
  end
20
29
  end
21
- end
30
+ end
@@ -0,0 +1,6 @@
1
+ Spree::Admin::ProductsController.class_eval do
2
+
3
+ def favorite_users
4
+ @users = @product.favorite_users.page(params[:page]).per(Spree::Config.favorite_products_per_page)
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ Spree::Admin::UsersController.class_eval do
2
+ def favorite_products
3
+ @favorite_products = @user.favorite_products.page(params[:page]).per(Spree::Config.favorite_products_per_page)
4
+ end
5
+ end
@@ -1,17 +1,18 @@
1
1
  module Spree
2
2
  class FavoriteProductsController < Spree::StoreController
3
3
 
4
- before_filter :authenticate_spree_user!
5
- before_filter :find_favorite_product, :only => :destroy
4
+ before_action :store_favorite_product_preference, only: :create
5
+ before_action :authenticate_spree_user!
6
+ before_action :find_favorite_product, only: :destroy
6
7
 
7
8
  def index
8
9
  @favorite_products = spree_current_user.favorite_products.page(params[:page]).per(Spree::Config.favorite_products_per_page)
9
10
  end
10
11
 
11
12
  def create
12
- favorite = spree_current_user.favorites.new :product_id => params[:id]
13
+ favorite = spree_current_user.favorites.new product_id: params[:id]
13
14
  if @success = favorite.save
14
- @message = "Product has been successfully marked as favorite"
15
+ @message = Spree.t(:success, scope: [:favorite_products, :create])
15
16
  else
16
17
  @message = favorite.errors.full_messages.to_sentence
17
18
  end
@@ -28,7 +29,14 @@ module Spree
28
29
 
29
30
  private
30
31
  def find_favorite_product
31
- @favorite = spree_current_user.favorites.joins(:product).readonly(false).where(:spree_products => {:id => params[:id]}).first
32
+ @favorite = spree_current_user.favorites.with_product_id(params[:id]).first
33
+ end
34
+
35
+ def store_favorite_product_preference
36
+ unless spree_current_user
37
+ session[:spree_user_return_to] = product_path(id: params[:id], favorite_product_id: params[:id])
38
+ redirect_to login_path, notice: Spree.t(:login_to_add_favorite)
39
+ end
32
40
  end
33
41
  end
34
- end
42
+ end
@@ -1,3 +1,4 @@
1
1
  Spree::AppConfiguration.class_eval do
2
2
  preference :favorite_products_per_page, :integer, default: 10
3
- end
3
+ preference :favorite_users_per_page, :integer, default: 10
4
+ end
@@ -1,9 +1,12 @@
1
1
  module Spree
2
2
  class Favorite < ActiveRecord::Base
3
- belongs_to :product
4
- belongs_to :user
5
- validates :user_id, :product_id, :presence => true
6
- validates :product_id, :uniqueness => { :scope => :user_id, :message => "already marked as favorite" }
7
- validates :product, :presence => { :message => "is invalid" }, :if => :product_id
3
+ with_options required: true do
4
+ belongs_to :product, counter_cache: :favorite_users_count
5
+ belongs_to :user
6
+ end
7
+
8
+ validates :product_id, uniqueness: { scope: :user_id, message: Spree.t(:duplicate_favorite), allow_blank: true }
9
+
10
+ scope :with_product_id, ->(id) { joins(:product).readonly(false).merge(Spree::Product.where(id: id)) }
8
11
  end
9
- end
12
+ end
@@ -1,12 +1,8 @@
1
1
  Spree::Product.class_eval do
2
- has_many :favorites, :dependent => :destroy
3
- has_many :favorite_users, :through => :favorites, :class_name => 'Spree::User', :source => 'user'
2
+ has_many :favorites, dependent: :destroy
3
+ has_many :favorite_users, through: :favorites, class_name: 'Spree::User', source: :user
4
4
 
5
- def self.favorite
6
- joins(:favorites).group('spree_favorites.product_id')
7
- end
8
-
9
- def self.order_by_favorite_users_count(asc=false)
10
- order("count(spree_favorites.user_id) #{asc ? 'asc' : 'desc'}")
11
- end
12
- end
5
+ scope :favorite, -> { joins(:favorites).distinct }
6
+
7
+ scope :order_by_favorite_users_count, ->(asc = false) { order(favorite_users_count: "#{asc ? 'asc' : 'desc'}") }
8
+ end
@@ -1,8 +1,8 @@
1
- Spree::User.class_eval do
2
- has_many :favorites, :dependent => :destroy
3
- has_many :favorite_products, :through => :favorites, :class_name => 'Spree::Product', :source => 'product'
1
+ Spree::User.class_eval do
2
+ has_many :favorites, dependent: :destroy
3
+ has_many :favorite_products, through: :favorites, class_name: 'Spree::Product', source: :product
4
4
 
5
5
  def has_favorite_product?(product_id)
6
- favorites.exists? :product_id => product_id
6
+ favorites.exists? product_id: product_id
7
7
  end
8
- end
8
+ end
@@ -1,13 +1,13 @@
1
1
  Deface::Override.new(
2
- :virtual_path => 'spree/admin/general_settings/edit',
3
- :name => 'add_favorite_products_per_page_configuration',
4
- :insert_before => "#preferences fieldset .form-actions",
5
- :text => %Q{
2
+ virtual_path: 'spree/admin/general_settings/edit',
3
+ name: 'add_favorite_products_per_page_configuration',
4
+ insert_before: "#preferences fieldset .form-actions",
5
+ text: %Q{
6
6
  <div class="row">
7
7
  <div class="col-md-6">
8
8
  <div class="form-group" data-hook="admin_general_setting_favorite_products_per_page">
9
9
  <%= label_tag :favorite_products_per_page, Spree.t(:favorite_products_per_page) %>
10
- <%= text_field_tag :favorite_products_per_page, Spree::Config[:favorite_products_per_page], :size => 3 %>
10
+ <%= text_field_tag :favorite_products_per_page, Spree::Config[:favorite_products_per_page], size: 3 %>
11
11
  </div>
12
12
  </div>
13
13
  </div>
@@ -1,6 +1,6 @@
1
1
  Deface::Override.new(
2
- :virtual_path => 'spree/admin/shared/sub_menu/_product',
3
- :name => 'select_products_tab',
4
- :insert_bottom => "#sidebar-product",
5
- :text => %Q{ <%= tab :favorite_products %> }
2
+ virtual_path: 'spree/admin/shared/sub_menu/_product',
3
+ name: 'select_products_tab',
4
+ insert_bottom: "#sidebar-product",
5
+ text: %Q{ <%= tab :favorite_products %> }
6
6
  )
@@ -0,0 +1,10 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/shared/_product_tabs',
3
+ name: 'add_favorite_users_tab_to_products',
4
+ insert_bottom: "[data-hook='admin_product_tabs']",
5
+ text: %Q{
6
+ <li<%== ' class="active"' if current == :favorited_by %>>
7
+ <%= link_to_with_icon 'user', Spree.t(:favorited_by), spree.favorite_users_admin_product_path(@product) %>
8
+ </li>
9
+ }
10
+ )
@@ -1,12 +1,13 @@
1
1
  Deface::Override.new(
2
- :virtual_path => 'spree/products/show',
3
- :name => 'add_link_to_mark_product_as_favorite',
4
- :insert_after => "div[itemprop='description']",
5
- :text => %Q{
2
+ virtual_path: 'spree/products/show',
3
+ name: 'add_link_to_mark_product_as_favorite',
4
+ surround_contents: "h1[itemprop='name']",
5
+ text: %Q{
6
+ <%= render_original %>
6
7
  <% if spree_user_signed_in? && spree_current_user.has_favorite_product?(@product.id) %>
7
- <%= link_to Spree.t(:unmark_as_favorite), favorite_product_path(:id => @product.id), :method => :delete, :remote => true, :class => 'favorite_link' %>
8
+ <%= link_to Spree.t(:unmark_as_favorite), favorite_product_path(id: @product.id), method: :delete, remote: true, class: 'favorite_link btn btn-primary pull-right', id: 'unmark-as-favorite' %>
8
9
  <% else %>
9
- <%= link_to Spree.t(:mark_as_favorite), favorite_products_path(:id => @product.id), :method => :post, :remote => spree_user_signed_in?, :class => 'favorite_link' %>
10
+ <%= link_to Spree.t(:mark_as_favorite), favorite_products_path(id: @product.id), method: :post, remote: spree_user_signed_in?, class: 'favorite_link btn btn-primary pull-right', id: 'mark-as-favorite' %>
10
11
  <% end %>
11
12
  }
12
- )
13
+ )
@@ -1,8 +1,8 @@
1
1
  Deface::Override.new(
2
- :virtual_path => "spree/shared/_nav_bar",
3
- :name => "add_link_to_users_favorite_products",
4
- :insert_before => "li#search-bar",
5
- :text => "<% if spree_current_user %><li><%= link_to 'Favorite Products', favorite_products_path %></li><% end %>",
6
- :sequence => { :before => "auth_shared_login_bar"}
2
+ virtual_path: "spree/shared/_main_nav_bar",
3
+ name: "add_link_to_users_favorite_products",
4
+ insert_after: "#home-link",
5
+ text: "<% if spree_current_user %><li><%= link_to 'Favorite Products', favorite_products_path %></li><% end %>",
6
+ sequence: { before: "auth_shared_login_bar"}
7
7
  )
8
8
 
@@ -0,0 +1,10 @@
1
+ Deface::Override.new(
2
+ virtual_path: 'spree/admin/users/_sidebar',
3
+ name: 'add_favorite_products_tab_to_users',
4
+ insert_bottom: "[data-hook='admin_user_tab_options']",
5
+ text: %Q{
6
+ <li<%== ' class="active"' if current == :favorite_products %>>
7
+ <%= link_to_with_icon 'th-large', Spree.t(:favorite_product), spree.favorite_products_admin_user_path(@user) %>
8
+ </li>
9
+ }
10
+ )
@@ -0,0 +1,25 @@
1
+ <% if @users.any? %>
2
+ <table class="table table-striped" id="listing_favorite_products_users">
3
+ <thead>
4
+ <tr data-hook="admin_products_index_headers">
5
+ <th><%= Spree.t(:email) %></th>
6
+ <th data-hook="admin_users_index_header_actions" class="actions text-right"> <%= Spree.t(:action) %></th>
7
+ </tr>
8
+ </thead>
9
+ <tbody>
10
+ <% @users.each do |user| %>
11
+ <tr id="<%= spree_dom_id user %>" data-hook="admin_users_index_rows">
12
+ <td class='user_email'><%=link_to user.email, edit_admin_user_url(user) %></td>
13
+ <td data-hook="admin_users_index_row_actions" class="actions actions-2 text-right">
14
+ <%= link_to_edit user,{ no_text: true, url: edit_admin_user_path(id: user) } %>
15
+ <%= link_to_delete user, no_text: true, url: admin_favorite_product_path(id: user.favorites.where(product_id: @product.id).first) %>
16
+ </td>
17
+ </tr>
18
+ <% end %>
19
+ </tbody>
20
+ </table>
21
+ <% else %>
22
+ <div class="no-objects-found">
23
+ <%= Spree.t(:no_results) %>
24
+ </div>
25
+ <% end %>
@@ -5,31 +5,24 @@
5
5
  <%= paginate @favorite_products %>
6
6
 
7
7
  <% if @favorite_products.any? %>
8
- <table class="table" id="listing_products">
9
- <colgroup>
10
- <col style="width: 15%;">
11
- <col style="width: 10%;">
12
- <col style="width: 38%;">
13
- <col style="width: 10%;">
14
- <col style="width: 17%;">
15
- <col style="width: 10%;">
16
- </colgroup>
8
+ <table class="table table-striped" id="listing_products">
17
9
  <thead>
18
10
  <tr data-hook="admin_products_index_headers">
19
11
  <th><%= Spree.t(:sku) %></th>
20
- <th colspan="2"><%= sort_link @search, :name, Spree.t(:name) %></th>
12
+ <th><%= Spree.t(:image) %></th>
13
+ <th><%= sort_link @search, :name, Spree.t(:name) %></th>
21
14
  <th><%= sort_link @search, :master_default_price_amount, Spree.t(:master_price) %></th>
22
- <th><%= sort_link @search, 'favorite_users_count', 'Favorite Users' %></th>
15
+ <th class="text-right"><%= sort_link @search, 'favorite_users_count', Spree.t(:favorite_users) %></th>
23
16
  </tr>
24
17
  </thead>
25
18
  <tbody>
26
19
  <% @favorite_products.each do |product| %>
27
- <tr <%= "style='color: red;'" if product.deleted? %> id="<%= spree_dom_id product %>" data-hook="admin_products_index_rows" class="<%= cycle('odd', 'even') %>">
28
- <td class="align-center"><%= product.sku rescue '' %></td>
29
- <td class="align-center"><%= mini_image(product) %></td>
20
+ <tr data-hook="admin_products_index_rows">
21
+ <td ><%= product.sku rescue '' %></td>
22
+ <td ><%= mini_image(product) %></td>
30
23
  <td><%= link_to product.try(:name), edit_admin_product_path(product) %></td>
31
- <td class="align-center"><%= product.display_price.to_html rescue '' %></td>
32
- <td class='align-center'><%= link_to product.favorite_users.count, users_admin_favorite_product_path(:id => product.id) %></td>
24
+ <td ><%= product.display_price.to_html rescue '' %></td>
25
+ <td class="text-right"><%= link_to product.favorite_users.count, users_admin_favorite_product_path(id: product.id) %></td>
33
26
  </tr>
34
27
  <% end %>
35
28
  </tbody>