Skip to content

Commit

Permalink
Merge pull request #1569 from fameandpartners/fix/spree-options-types…
Browse files Browse the repository at this point in the history
…-form

[Feature] Assign new colors for the products in the admin area
  • Loading branch information
tiagoamaro committed Apr 25, 2016
2 parents 1cef993 + f314be1 commit bb8a3ee
Show file tree
Hide file tree
Showing 23 changed files with 240 additions and 33 deletions.
5 changes: 5 additions & 0 deletions Gemfile.lock
Expand Up @@ -115,6 +115,7 @@ PATH
admin_ui (0.0.1)
active_link_to
cancan
chosen-rails
datagrid
font-awesome-rails
kaminari
Expand Down Expand Up @@ -238,6 +239,10 @@ GEM
timers (~> 1.1.0)
childprocess (0.5.9)
ffi (~> 1.0, >= 1.0.11)
chosen-rails (1.5.1)
coffee-rails (>= 3.2)
railties (>= 3.0)
sass-rails (>= 3.2)
chronic (0.10.2)
chunky_png (1.3.4)
ckeditor (4.1.1)
Expand Down
4 changes: 3 additions & 1 deletion app/models/product_color_value.rb
@@ -1,5 +1,5 @@
class ProductColorValue < ActiveRecord::Base
attr_accessible :option_value
attr_accessible :option_value, :product_id, :option_value_id, :active, :custom

belongs_to :product, class_name: 'Spree::Product', inverse_of: :product_color_values
belongs_to :option_value,
Expand All @@ -8,6 +8,8 @@ class ProductColorValue < ActiveRecord::Base

has_many :images, as: :viewable, order: :position, dependent: :destroy, class_name: "Spree::Image"

validates :product_id, :option_value_id, presence: true

def recommended?
! custom?
end
Expand Down
5 changes: 5 additions & 0 deletions app/models/spree/product_decorator.rb
Expand Up @@ -39,6 +39,7 @@
:size_chart,
:related_outerwear_ids

attr_reader :name_with_sku

scope :has_options, lambda { |option_type, value_ids|
joins(variants: :option_values).where(
Expand Down Expand Up @@ -73,6 +74,10 @@
SIZE_CHARTS = SizeChart::CHARTS.keys
validates_inclusion_of :size_chart, in: SIZE_CHARTS

def name_with_sku
"#{name} (SKU: #{sku})"
end

def new_size_chart?
size_chart == SIZE_CHARTS.last
end
Expand Down
7 changes: 7 additions & 0 deletions config/initializers/rack.rb
@@ -0,0 +1,7 @@
if Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new('4')
Rack::Utils.multipart_part_limit = 300
else
puts '------------------------------------------------------------------------------------------------------'
puts 'Rails is on its 4 version! Upgrade Rack to its latest version to solve rack/rack#814, "Too many open files"'
puts '------------------------------------------------------------------------------------------------------'
end
2 changes: 1 addition & 1 deletion engines/admin_ui/admin_ui.gemspec
Expand Up @@ -32,7 +32,7 @@ Gem::Specification.new do |s|
# Theme
# s.add_dependency "inspinia-rails"
s.add_dependency "font-awesome-rails"

s.add_dependency "chosen-rails"

# Even with this here, the helper is not loaded unless the main app
# also inlcudes 'active_link_to' in it's Gemfile.
Expand Down
1 change: 1 addition & 0 deletions engines/admin_ui/app/assets/javascripts/admin_ui.js
Expand Up @@ -13,6 +13,7 @@
//= require libs/underscore-min
//= require inspinia-rails
//= require jquery-ui
//= require chosen-jquery

//= require react
//= require react_ujs
Expand Down
@@ -0,0 +1,7 @@
$ ->
# enable chosen js
$('.chosen-select').chosen
allow_single_deselect: true
no_results_text: 'No results matched'
width: '400px'

@@ -0,0 +1,16 @@
$ ->
urlTemplate = '/fame_admin/product_colors/colors_options/:product_id'
productSelect = $('#product_color_value_product_id')
colorSelect = $('#product_color_value_option_value_id')

productSelect.on 'change', =>
colorSelect.html('<option></option>')
url = urlTemplate.replace(/:product_id/, productSelect.val()) if productSelect.val()
if url
$.getJSON url, (data) =>
$.each data['product_colors'], (index, el) =>
colorSelect.append "<option value='#{el.id}'>#{el.name}</option>"
colorSelect.trigger("chosen:updated")
else
colorSelect.trigger("chosen:updated")

1 change: 1 addition & 0 deletions engines/admin_ui/app/assets/stylesheets/admin_ui.css
Expand Up @@ -10,6 +10,7 @@
*
*= require 'inspinia-rails'
*= require 'jquery-ui'
*= require 'chosen'
*= require_self
*= require_tree .
* Loaded from the main application styles
Expand Down
@@ -1,6 +1,9 @@

.pages {
.btn.save {
margin-right:1em;
}
}

.ibox-content.colors {
height: 280px;
}
Expand Up @@ -2,6 +2,7 @@

module AdminUi
class ProductColorsController < AdminUi::ApplicationController

def index
@collection = ProductColorValuesGrid.new(params[:product_color_values_grid])
respond_to do |f|
Expand All @@ -17,28 +18,65 @@ def index
end
end

def new
@product_color_value = ProductColorValue.new
end

def create
@product_color_value = ProductColorValue.new(params[:product_color_value])
if @product_color_value.save
message = { success: "Color '#{@product_color_value.option_value.name}'
for the product '#{@product_color_value.product.name}' successfully created" }
redirect_to product_colors_path, flash: message
else
render :new
end
end

def edit
@product_color_value = ProductColorValue.find(params[:id].to_i)
@product_color_value = ProductColorValue.find(params[:id])
end

def update
@product_color_value = ProductColorValue.find(params[:id].to_i)
@product_color_value = ProductColorValue.find(params[:id])

if @product_color_value.update_attributes!(params[:product_color_value])
color_state = @product_color_value.active? ? 'Active' : 'Inactive'
message = { success: "Color '#{@product_color_value.option_value.name}'
for the product '#{@product_color_value.product.name}' is now #{color_state}" }
else
message = { error: 'A problem occurred on saving. Please try again later.' }
end

redirect_to product_colors_path, flash: message
end

message = { error: 'A problem occurred saving.' }
def destroy
@product_color_value = ProductColorValue.find(params[:id])
@product_color_value.destroy
redirect_to product_colors_path, flash: { success: 'Color successfully removed' }
end

if new_active_state = params[:product_color_value][:active]
def colors_options_json
render json: get_color_options(params[:product_id]).map { |c| {id: c.id, name: c.name} }
end

@product_color_value.active = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(new_active_state)
@product_color_value.custom = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(params[:product_color_value][:custom])
private

if @product_color_value.save
new_state = @product_color_value.active? ? 'active' : 'inactive'
helper_method :products, :color_options

message = { success: "Product Color is now (#{new_state})" }
end
end
def products
Spree::Product.active
end

redirect_to product_colors_path, flash: message
def color_options
get_color_options(params[:product_color_value].try(:[], :product_id))
end

def get_color_options(product_id)
associated_colors = ProductColorValue.where(product_id: product_id).pluck(:option_value_id)
Spree::OptionValue.colors.where('id NOT IN (?)', associated_colors)
end

end
end
6 changes: 6 additions & 0 deletions engines/admin_ui/app/models/product_color_values_grid.rb
Expand Up @@ -84,4 +84,10 @@ class ProductColorValuesGrid
content_tag(:i, '', class: "fa fa-#{class_name} fa-lg")
end
end

column :remove? do |pcv|
format(pcv.id) do
button_to('Remove', product_color_path(pcv), action: 'destroy', method: 'delete', class: 'btn btn-danger', data: { confirm: 'Are you sure?' })
end
end
end
43 changes: 26 additions & 17 deletions engines/admin_ui/app/views/admin_ui/product_colors/edit.html.slim
Expand Up @@ -6,30 +6,38 @@
h5
=> @product_color_value.product.name
=> @product_color_value.option_value.presentation
.ibox-content
.ibox-content.colors
h5
= link_to(@product_color_value.product.name, spree.admin_product_path(@product_color_value.product))
ul
li = @product_color_value.product.sku
li = @product_color_value.product.active?
li = @product_color_value.option_value.presentation
li = @product_color_value.option_value.name

= render 'admin_ui/product_colors/colour_preview', color_name: @product_color_value.option_value.name
.row
.col-md-3 : p : b SKU
.col-md-9 : span.label #{@product_color_value.product.sku}
.row
.col-md-3 : p : b Is active
.col-md-9 : span.label #{@product_color_value.product.active?}
.row
.col-md-3 : p : b Presentation
.col-md-9 : span.label #{@product_color_value.option_value.presentation}
.row
.col-md-3 : p : b Name
.col-md-9 : span.label #{@product_color_value.option_value.name}
.row
.col-md-3 : p : b Visual
.col-md-9 = render 'admin_ui/product_colors/colour_preview', color_name: @product_color_value.option_value.name
.col-lg-6
.ibox
.ibox-title
h5 Enable / Disable
.ibox-content
.ibox-content.colors
= form_for(@product_color_value, url: product_color_path(@product_color_value)) do |f|
.form-group
= f.check_box :active, class: 'form-control'
= f.label :active
= f.check_box :custom, class: 'form-control'
= f.label :custom
.form-group
= f.submit 'Save'
alert.alert-warning
= f.submit 'Update', class: 'btn btn-primary'
alert.alert-warning
| Warning: updating colors custom/active attributes require product reindexing. To do it, proceed to the &nbsp;
= link_to 'product index section', backend_product_indexes_path
.row
Expand All @@ -38,9 +46,10 @@
.ibox-title
h5 Images
.ibox-content
ul
- @product_color_value.images.each do |image|
li
= image.attachment_file_name
br
= image_tag image.attachment.url
- @product_color_value.images.each do |image|
= image.attachment_file_name
br
= image_tag image.attachment.url
br
br

@@ -1,2 +1,7 @@
- content_for :page_title do
| Colors variants

= render 'admin_ui/grid/grid_collection_filters', collection_url: product_colors_path
= link_to 'Add new color to product', new_product_color_path, class: 'btn btn-primary'
br
= render 'admin_ui/grid/paginated_collection_grid'
23 changes: 23 additions & 0 deletions engines/admin_ui/app/views/admin_ui/product_colors/new.html.slim
@@ -0,0 +1,23 @@
.pages.wrapper.wrapper-content
= form_for @product_color_value, :url => {:action => "create"}, method: :post, :html => {:class => 'form-horizontal'} do |f|
.ibox.float-e-margins
.ibox-title
h5 Add new color to the product
.ibox-content
.form-group
label.col-sm-2.control-label Product
.col-sm-10 = f.collection_select :product_id, products, :id, :name_with_sku,
{ include_blank: true }, { class: 'chosen-select', data: { selectable_target: '#product_color_value_option_value_id' }}
.form-group
label.col-sm-2.control-label Colors Options
.col-sm-10 = f.collection_select :option_value_id, color_options, :id, :name, { include_blank: true }, { class: 'chosen-select' }
.form-group
label.col-sm-2.control-label Active
.col-sm-10 = f.check_box :active
.form-group
label.col-sm-2.control-label Custom
.col-sm-10 = f.check_box :custom
.form-group
.col-sm-2
.col-sm-10
= f.submit 'Create', class: 'btn btn-primary'
6 changes: 5 additions & 1 deletion engines/admin_ui/config/routes.rb
Expand Up @@ -51,7 +51,11 @@
end

resources :variants
resources :product_colors
resources :product_colors do
collection do
get 'colors_options/:product_id' => 'product_colors#colors_options_json'
end
end

namespace :content do
resources :pages
Expand Down
1 change: 1 addition & 0 deletions engines/admin_ui/lib/admin_ui/engine.rb
@@ -1,5 +1,6 @@
module AdminUi
class Engine < ::Rails::Engine
require 'chosen-rails'
isolate_namespace AdminUi
initializer :assets, :group => :all do |app|
app.config.assets.precompile += %w{ admin_ui.css }
Expand Down
22 changes: 22 additions & 0 deletions engines/admin_ui/spec/acceptance/product_colors.feature
@@ -0,0 +1,22 @@
Feature: Assign colors to products

Background:
Given A sample database with valid data
And The example admin is signed in

@javascript
Scenario:
When I am on the product colors page
And I click on "Add new color to product" link
And I select "Connie" product from chosen select box
And I select "Coral" color from chosen select box
And I click on "Create" button
Then I should see "Color 'coral' for the product 'Connie' successfully created"

Scenario:
When I am on the product colors page
And I click on "Add new color to product" link
And I select "Connie" product from chosen select box
And I click on "Create" button
Then I should see "can't be blank"

16 changes: 16 additions & 0 deletions engines/admin_ui/spec/support/steps/admin_steps.rb
@@ -0,0 +1,16 @@
module Acceptance
module AdminSteps
step 'The example admin is signed in' do
visit '/login'
fill_in('Email', with: 'admin@example.com')
fill_in('Password', with: '123456')
click_button 'Login'
visit '/fame_admin'
expect(page).to have_text('Welcome to #new Admin')
end
end
end

RSpec.configure do |config|
config.include Acceptance::AdminSteps, type: :feature
end

0 comments on commit bb8a3ee

Please sign in to comment.