spree_favorite_products 3.0.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +1 -1
- data/Gemfile +10 -11
- data/README.md +8 -25
- data/Rakefile +1 -2
- data/app/assets/javascripts/spree/backend/spree_favorite_products.js +0 -0
- data/app/assets/javascripts/spree/frontend/spree_favorite_products.js +23 -0
- data/app/assets/stylesheets/spree/backend/spree_favorite_products.css +0 -0
- data/app/assets/stylesheets/spree/frontend/spree_favorite_products.css +0 -0
- data/app/controllers/spree/admin/favorite_products_controller.rb +14 -5
- data/app/controllers/spree/admin/products_controller_decorator.rb +6 -0
- data/app/controllers/spree/admin/users_controller_decorator.rb +5 -0
- data/app/controllers/spree/favorite_products_controller.rb +14 -6
- data/app/models/spree/app_configuration_decorator.rb +2 -1
- data/app/models/spree/favorite.rb +9 -6
- data/app/models/spree/product_decorator.rb +6 -10
- data/app/models/spree/user_decorator.rb +5 -5
- data/app/overrides/add_favorite_products_per_page_configuration.rb +5 -5
- data/app/overrides/add_favorite_products_to_products_tab.rb +4 -4
- data/app/overrides/add_favorite_users_tab_to_products.rb +10 -0
- data/app/overrides/add_link_to_mark_product_as_favorite.rb +8 -7
- data/app/overrides/add_link_to_users_favorite_products.rb +5 -5
- data/app/overrides/addd_favorite_products_tab_to_users.rb +10 -0
- data/app/views/spree/admin/favorite_products/_users.html.erb +25 -0
- data/app/views/spree/admin/favorite_products/index.html.erb +9 -16
- data/app/views/spree/admin/products/favorite_users.html.erb +14 -0
- data/app/views/spree/admin/users/favorite_products.html.erb +50 -0
- data/app/views/spree/favorite_products/destroy.js.erb +1 -1
- data/app/views/spree/favorite_products/index.html.erb +6 -6
- data/config/locales/bg.yml +13 -0
- data/config/locales/en.yml +21 -3
- data/config/locales/pl.yml +19 -0
- data/config/routes.rb +11 -3
- data/db/migrate/20130705080641_create_table_favorites.rb +1 -1
- data/db/migrate/20130710105100_rename_favorites_to_spree_favorites.rb +1 -1
- data/db/migrate/20160304152800_add_favorites_user_counts_to_product.rb +6 -0
- data/lib/generators/spree_favorite_products/install/install_generator.rb +4 -3
- data/spec/controllers/spree/admin/favorite_products_controller_spec.rb +31 -41
- data/spec/controllers/spree/admin/products_controller_decorator_spec.rb +28 -0
- data/spec/controllers/spree/admin/users_controller_decorator_spec.rb +28 -0
- data/spec/controllers/spree/favorite_products_controller_spec.rb +25 -33
- data/spec/models/spree/app_configuration_decorator_spec.rb +2 -2
- data/spec/models/spree/favorite_spec.rb +21 -19
- data/spec/models/spree/product_decorator_spec.rb +16 -16
- data/spec/models/spree/user_decorator_spec.rb +9 -8
- data/spec/spec_helper.rb +21 -0
- data/spree_favorite_products.gemspec +9 -5
- metadata +80 -7
- data/Gemfile.lock +0 -345
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c1b87a8f8374a8725e42a237cd480c073b4b6de
|
4
|
+
data.tar.gz: 737eac610412ab5534ec669d222f95ea3e1378d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed5fc3f665c0d97711605b053c5577ada2c60a36b962181d3298af38122054e4d04d09fa12a77124ce85087fa612f6864e985b2b73606f9bced90f2aacace407
|
7
|
+
data.tar.gz: bdb7d0aa97295a80e25969276eab56aef30bae46d94f20a42ae44b75d47ddc4278083c07c74bbf276ba0a669fa3a98722eecc6a9bec5a1962882e5238c7a0ac7
|
data/.gitignore
CHANGED
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', '
|
5
|
-
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '
|
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
|
-
|
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
|
15
|
-
gem 'shoulda-matchers', '
|
16
|
-
gem 'simplecov', :
|
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
|
2
|
-
|
1
|
+
Spree Favorite Products
|
2
|
+
=======================
|
3
3
|
|
4
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
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'
|
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)
|
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 :
|
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
|
File without changes
|
@@ -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
|
+
);
|
File without changes
|
File without changes
|
@@ -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
|
11
|
-
@
|
12
|
-
|
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
|
@@ -1,17 +1,18 @@
|
|
1
1
|
module Spree
|
2
2
|
class FavoriteProductsController < Spree::StoreController
|
3
3
|
|
4
|
-
|
5
|
-
|
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 :
|
13
|
+
favorite = spree_current_user.favorites.new product_id: params[:id]
|
13
14
|
if @success = favorite.save
|
14
|
-
@message =
|
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.
|
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,9 +1,12 @@
|
|
1
1
|
module Spree
|
2
2
|
class Favorite < ActiveRecord::Base
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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, :
|
3
|
-
has_many :favorite_users, :
|
2
|
+
has_many :favorites, dependent: :destroy
|
3
|
+
has_many :favorite_users, through: :favorites, class_name: 'Spree::User', source: :user
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
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, :
|
3
|
-
has_many :favorite_products, :
|
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? :
|
6
|
+
favorites.exists? product_id: product_id
|
7
7
|
end
|
8
|
-
end
|
8
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
Deface::Override.new(
|
2
|
-
:
|
3
|
-
:
|
4
|
-
:
|
5
|
-
:
|
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], :
|
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
|
-
:
|
3
|
-
:
|
4
|
-
:
|
5
|
-
:
|
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
|
-
:
|
3
|
-
:
|
4
|
-
:
|
5
|
-
:
|
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(:
|
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(:
|
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
|
-
:
|
3
|
-
:
|
4
|
-
:
|
5
|
-
:
|
6
|
-
:
|
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
|
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',
|
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
|
28
|
-
<td
|
29
|
-
<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
|
32
|
-
<td class=
|
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>
|