Commit 1e4063df909242eb8f9dc4cd157041fd87613943
Committed by
Joenio Costa
1 parent
b361aebc
Exists in
master
and in
29 other branches
Create a block to make the products highlighted:
* This block must be available to Enterprises and the enterprise administrator could choose what products will be highlighted * The environment could have this block and in this case the products are choosen randomically (ActionItem1576)
Showing
21 changed files
with
586 additions
and
8 deletions
Show diff stats
app/controllers/admin/environment_design_controller.rb
@@ -3,7 +3,7 @@ class EnvironmentDesignController < BoxOrganizerController | @@ -3,7 +3,7 @@ class EnvironmentDesignController < BoxOrganizerController | ||
3 | protect 'edit_environment_design', :environment | 3 | protect 'edit_environment_design', :environment |
4 | 4 | ||
5 | def available_blocks | 5 | def available_blocks |
6 | - @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock ] | 6 | + @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock ] |
7 | end | 7 | end |
8 | 8 | ||
9 | end | 9 | end |
app/controllers/my_profile/profile_design_controller.rb
@@ -24,6 +24,7 @@ class ProfileDesignController < BoxOrganizerController | @@ -24,6 +24,7 @@ class ProfileDesignController < BoxOrganizerController | ||
24 | if profile.enterprise? | 24 | if profile.enterprise? |
25 | blocks << DisabledEnterpriseMessageBlock | 25 | blocks << DisabledEnterpriseMessageBlock |
26 | blocks << HighlightsBlock | 26 | blocks << HighlightsBlock |
27 | + blocks << FeaturedProductsBlock | ||
27 | end | 28 | end |
28 | 29 | ||
29 | # product block exclusive for enterprises in environments that permits it | 30 | # product block exclusive for enterprises in environments that permits it |
app/helpers/application_helper.rb
@@ -960,4 +960,9 @@ module ApplicationHelper | @@ -960,4 +960,9 @@ module ApplicationHelper | ||
960 | text_field_tag(name, value, options.merge(:class => 'colorpicker_field')) | 960 | text_field_tag(name, value, options.merge(:class => 'colorpicker_field')) |
961 | end | 961 | end |
962 | 962 | ||
963 | + # for now force currency to Brazillian format, like: "12.345,20" | ||
964 | + def float_to_currency(price) | ||
965 | + number_to_currency(price, :unit => 'R$', :separator => ',', :delimiter => '.') | ||
966 | + end | ||
967 | + | ||
963 | end | 968 | end |
app/models/enterprise.rb
@@ -51,6 +51,10 @@ class Enterprise < Organization | @@ -51,6 +51,10 @@ class Enterprise < Organization | ||
51 | environment ? environment.active_enterprise_fields : [] | 51 | environment ? environment.active_enterprise_fields : [] |
52 | end | 52 | end |
53 | 53 | ||
54 | + def highlighted_products_with_image(options = {}) | ||
55 | + Product.find(:all, {:conditions => {:highlighted => true}, :joins => :image}.merge(options)) | ||
56 | + end | ||
57 | + | ||
54 | def required_fields | 58 | def required_fields |
55 | environment ? environment.required_enterprise_fields : [] | 59 | environment ? environment.required_enterprise_fields : [] |
56 | end | 60 | end |
app/models/environment.rb
@@ -628,4 +628,9 @@ class Environment < ActiveRecord::Base | @@ -628,4 +628,9 @@ class Environment < ActiveRecord::Base | ||
628 | end | 628 | end |
629 | end | 629 | end |
630 | 630 | ||
631 | + def highlighted_products_with_image(options = {}) | ||
632 | + Product.find(:all, {:conditions => {:highlighted => true, :enterprise_id => self.enterprises.find(:all, :select => :id) }, :joins => :image}.merge(options)) | ||
633 | + end | ||
634 | + | ||
631 | end | 635 | end |
636 | + |
@@ -0,0 +1,35 @@ | @@ -0,0 +1,35 @@ | ||
1 | +class FeaturedProductsBlock < Block | ||
2 | + | ||
3 | + settings_items :product_ids, :type => Array, :default => [] | ||
4 | + settings_items :groups_of, :type => :integer, :default => 3 | ||
5 | + settings_items :speed, :type => :integer, :default => 1000 | ||
6 | + settings_items :reflect, :type => :boolean, :default => true | ||
7 | + | ||
8 | + before_save do |block| | ||
9 | + if block.owner.kind_of?(Environment) && block.product_ids.blank? | ||
10 | + seed = block.owner.products.count | ||
11 | + block.product_ids = block.owner.highlighted_products_with_image(:offset => (rand(seed) % (seed - block.groups_of * 3)), :limit => block.groups_of * 3).map(&:id) | ||
12 | + end | ||
13 | + block.groups_of = block.groups_of.to_i | ||
14 | + end | ||
15 | + | ||
16 | + def self.description | ||
17 | + _('Featured Products') | ||
18 | + end | ||
19 | + | ||
20 | + def products | ||
21 | + Product.find(self.product_ids) || [] | ||
22 | + end | ||
23 | + | ||
24 | + def products_for_selection | ||
25 | + self.owner.highlighted_products_with_image | ||
26 | + end | ||
27 | + | ||
28 | + def content | ||
29 | + block = self | ||
30 | + lambda do | ||
31 | + render :file => 'blocks/featured_products', :locals => { :block => block } | ||
32 | + end | ||
33 | + end | ||
34 | + | ||
35 | +end |
@@ -0,0 +1,55 @@ | @@ -0,0 +1,55 @@ | ||
1 | +<%= block_title(block.title) %> | ||
2 | +<% unless block.products.blank? %> | ||
3 | + <%= link_to content_tag(:span, _('Previous')), '#', :class => 'featured-product-prev featured-product-arrow' %> | ||
4 | + <div class="featured-products-block-container"> | ||
5 | + <ul class="featured-products-list"> | ||
6 | + <% block.products.in_groups_of(block.groups_of).each do |group| %> | ||
7 | + <li class="featured-products-group"> | ||
8 | + <div class="featured-product-items"> | ||
9 | + <ul> | ||
10 | + <% group.reject{ |x| x.nil? }.each_with_index do |p, i| %> | ||
11 | + <li class="featured-product-item"> | ||
12 | + <%= link_to content_tag(:img, nil, :src => p.image.public_filename(:thumb), :alt => p.name, :class => ('reflect' if block.reflect)), product_path(p.enterprise.identifier, p), :class => 'featured-product-image' %> | ||
13 | + <div class="featured-product-info position-<%= i + 1 %>" style="display: none"> | ||
14 | + <div class="featured-product-text"> | ||
15 | + <h3><%= p.name %></h3> | ||
16 | + <p class="featured-product-price"><%= float_to_currency(p.price) %></p> | ||
17 | + <p class="featured-product-desc"><%= p.description.chars[0...50].to_s + '...' %></p> | ||
18 | + <p><%= link_to _('See More'), product_path(p.enterprise.identifier, p), :class => 'featured-product-link' %></p> | ||
19 | + </div> | ||
20 | + </div> | ||
21 | + </li> | ||
22 | + <% end %> | ||
23 | + </ul> | ||
24 | + </div> | ||
25 | + </li> | ||
26 | + <% end %> | ||
27 | + </ul> | ||
28 | + </div> | ||
29 | + <%= link_to content_tag(:span, _('Next')), '#', :class => 'featured-product-next featured-product-arrow' %> | ||
30 | + <script type="text/javascript"> | ||
31 | + (function($) { | ||
32 | + var options = { | ||
33 | + fx : 'scrollHorz', | ||
34 | + timeout: 0, | ||
35 | + prev: '#block-<%= block.id %> .featured-product-prev', | ||
36 | + next: '#block-<%= block.id %> .featured-product-next', | ||
37 | + speed: <%= block.speed || 2000 %> | ||
38 | + } | ||
39 | + $('#block-<%= block.id %> .featured-products-list').cycle(options); | ||
40 | + | ||
41 | + $(document).ready(function(){ | ||
42 | + $(".featured-product-item").hover( | ||
43 | + function() { | ||
44 | + $(".featured-product-info", this).fadeIn('slow'); | ||
45 | + }, | ||
46 | + function() { | ||
47 | + $(".featured-product-info", this).fadeOut('slow'); | ||
48 | + }); | ||
49 | + }); | ||
50 | + })(jQuery); | ||
51 | + </script> | ||
52 | + <p class="featured-products-footer"></p> | ||
53 | +<% else %> | ||
54 | + <em><%= _('Please, edit this block and choose some products') %></em> | ||
55 | +<% end %> |
@@ -0,0 +1,8 @@ | @@ -0,0 +1,8 @@ | ||
1 | +<strong><%= _('Featured Products') %></strong> | ||
2 | +<div id='edit-featured-products-block'> | ||
3 | + <p><%= label_tag _('Choose some products') %></p> | ||
4 | + <p><%= select_tag 'block[product_ids][]', options_for_select(@block.products_for_selection.map{|p| [p.name, p.id.to_s]}, @block.product_ids), :multiple => true %></p> | ||
5 | + <p><%= labelled_form_field check_box(:block, :reflect) + _('Reflect products'), '' %></p> | ||
6 | + <p><%= labelled_form_field(_('Transition speed (in seconds)'), select('block', 'speed', (1..10).to_a.collect{|i| [i, i*1000] })) %> | ||
7 | + <p><%= labelled_form_field(_('In groups of'), select('block', 'groups_of', (1..10).to_a)) %> | ||
8 | +</div> |
app/views/layouts/_javascript.rhtml
1 | -<%= javascript_include_tag :defaults, 'jquery-latest.js', 'jquery.noconflict.js', 'jquery.cycle.all.min.js', 'thickbox.js', 'lightbox', 'colorpicker', 'colorpicker-noosfero', :cache => 'cache-general' %> | 1 | +<%= javascript_include_tag :defaults, 'jquery-latest.js', 'jquery.noconflict.js', 'jquery.cycle.all.min.js', 'thickbox.js', 'lightbox', 'colorpicker', 'colorpicker-noosfero', 'reflection', :cache => 'cache-general' %> |
app/views/manage_products/_form.rhtml
@@ -6,6 +6,7 @@ | @@ -6,6 +6,7 @@ | ||
6 | <%= required display_form_field( _('Name:'), f.text_field(:name) ) %> | 6 | <%= required display_form_field( _('Name:'), f.text_field(:name) ) %> |
7 | <%= display_form_field( _('Price:'), f.text_field(:price) ) %> | 7 | <%= display_form_field( _('Price:'), f.text_field(:price) ) %> |
8 | <%= display_form_field( _('Description:'), f.text_area(:description, :rows => 10) ) %> | 8 | <%= display_form_field( _('Description:'), f.text_area(:description, :rows => 10) ) %> |
9 | + <%= labelled_form_field(f.check_box(:highlighted) + _('Highlight this product'),'') %> | ||
9 | <% f.fields_for :image_builder, @product.image do |i| %> | 10 | <% f.fields_for :image_builder, @product.image do |i| %> |
10 | <%= file_field_or_thumbnail(_('Image:'), @product.image, i) %> | 11 | <%= file_field_or_thumbnail(_('Image:'), @product.image, i) %> |
11 | <% end %> | 12 | <% end %> |
db/schema.rb
@@ -9,7 +9,8 @@ | @@ -9,7 +9,8 @@ | ||
9 | # | 9 | # |
10 | # It's strongly recommended to check this file into your version control system. | 10 | # It's strongly recommended to check this file into your version control system. |
11 | 11 | ||
12 | -ActiveRecord::Schema.define(:version => 20100514133346) do | 12 | + |
13 | +ActiveRecord::Schema.define(:version => 20100619031945) do | ||
13 | 14 | ||
14 | create_table "article_versions", :force => true do |t| | 15 | create_table "article_versions", :force => true do |t| |
15 | t.integer "article_id" | 16 | t.integer "article_id" |
@@ -240,6 +241,7 @@ ActiveRecord::Schema.define(:version => 20100514133346) do | @@ -240,6 +241,7 @@ ActiveRecord::Schema.define(:version => 20100514133346) do | ||
240 | t.datetime "updated_at" | 241 | t.datetime "updated_at" |
241 | t.float "lat" | 242 | t.float "lat" |
242 | t.float "lng" | 243 | t.float "lng" |
244 | + t.boolean "highlighted" | ||
243 | end | 245 | end |
244 | 246 | ||
245 | add_index "products", ["enterprise_id"], :name => "index_products_on_enterprise_id" | 247 | add_index "products", ["enterprise_id"], :name => "index_products_on_enterprise_id" |
@@ -0,0 +1,177 @@ | @@ -0,0 +1,177 @@ | ||
1 | +/** | ||
2 | + * reflection.js v2.0 | ||
3 | + * http://cow.neondragon.net/stuff/reflection/ | ||
4 | + * Freely distributable under MIT-style license. | ||
5 | + */ | ||
6 | + | ||
7 | +/* From prototype.js */ | ||
8 | +if (!document.myGetElementsByClassName) { | ||
9 | + document.myGetElementsByClassName = function(className) { | ||
10 | + var children = document.getElementsByTagName('*') || document.all; | ||
11 | + var elements = new Array(); | ||
12 | + | ||
13 | + for (var i = 0; i < children.length; i++) { | ||
14 | + var child = children[i]; | ||
15 | + var classNames = child.className.split(' '); | ||
16 | + for (var j = 0; j < classNames.length; j++) { | ||
17 | + if (classNames[j] == className) { | ||
18 | + elements.push(child); | ||
19 | + break; | ||
20 | + } | ||
21 | + } | ||
22 | + } | ||
23 | + return elements; | ||
24 | + } | ||
25 | +} | ||
26 | + | ||
27 | +var Reflection = { | ||
28 | + defaultHeight : 0.5, | ||
29 | + defaultOpacity: 0.5, | ||
30 | + | ||
31 | + add: function(image, options) { | ||
32 | + Reflection.remove(image); | ||
33 | + | ||
34 | + doptions = { "height" : Reflection.defaultHeight, "opacity" : Reflection.defaultOpacity } | ||
35 | + if (options) { | ||
36 | + for (var i in doptions) { | ||
37 | + if (!options[i]) { | ||
38 | + options[i] = doptions[i]; | ||
39 | + } | ||
40 | + } | ||
41 | + } else { | ||
42 | + options = doptions; | ||
43 | + } | ||
44 | + | ||
45 | + try { | ||
46 | + var d = document.createElement('div'); | ||
47 | + var p = image; | ||
48 | + | ||
49 | + var classes = p.className.split(' '); | ||
50 | + var newClasses = ''; | ||
51 | + for (j=0;j<classes.length;j++) { | ||
52 | + if (classes[j] != "reflect") { | ||
53 | + if (newClasses) { | ||
54 | + newClasses += ' ' | ||
55 | + } | ||
56 | + | ||
57 | + newClasses += classes[j]; | ||
58 | + } | ||
59 | + } | ||
60 | + | ||
61 | + var reflectionHeight = Math.floor(p.height*options['height']); | ||
62 | + var divHeight = Math.floor(p.height*(1+options['height'])); | ||
63 | + | ||
64 | + var reflectionWidth = p.width; | ||
65 | + | ||
66 | + if (document.all && !window.opera) { | ||
67 | + /* Fix hyperlinks */ | ||
68 | + if(p.parentElement.tagName == 'A') { | ||
69 | + var d = document.createElement('a'); | ||
70 | + d.href = p.parentElement.href; | ||
71 | + } | ||
72 | + | ||
73 | + /* Copy original image's classes & styles to div */ | ||
74 | + d.className = newClasses; | ||
75 | + p.className = 'reflected'; | ||
76 | + | ||
77 | + d.style.cssText = p.style.cssText; | ||
78 | + p.style.cssText = 'vertical-align: bottom'; | ||
79 | + | ||
80 | + var reflection = document.createElement('img'); | ||
81 | + reflection.src = p.src; | ||
82 | + reflection.style.width = reflectionWidth+'px'; | ||
83 | + reflection.style.display = 'block'; | ||
84 | + reflection.style.height = p.height+"px"; | ||
85 | + | ||
86 | + reflection.style.marginBottom = "-"+(p.height-reflectionHeight)+'px'; | ||
87 | + reflection.style.filter = 'flipv progid:DXImageTransform.Microsoft.Alpha(opacity='+(options['opacity']*100)+', style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy='+(options['height']*100)+')'; | ||
88 | + | ||
89 | + d.style.width = reflectionWidth+'px'; | ||
90 | + d.style.height = divHeight+'px'; | ||
91 | + p.parentNode.replaceChild(d, p); | ||
92 | + | ||
93 | + d.appendChild(p); | ||
94 | + d.appendChild(reflection); | ||
95 | + } else { | ||
96 | + var canvas = document.createElement('canvas'); | ||
97 | + if (canvas.getContext) { | ||
98 | + /* Copy original image's classes & styles to div */ | ||
99 | + d.className = newClasses; | ||
100 | + p.className = 'reflected'; | ||
101 | + | ||
102 | + d.style.cssText = p.style.cssText; | ||
103 | + p.style.cssText = 'vertical-align: bottom'; | ||
104 | + | ||
105 | + var context = canvas.getContext("2d"); | ||
106 | + | ||
107 | + canvas.style.height = reflectionHeight+'px'; | ||
108 | + canvas.style.width = reflectionWidth+'px'; | ||
109 | + canvas.height = reflectionHeight; | ||
110 | + canvas.width = reflectionWidth; | ||
111 | + | ||
112 | + d.style.width = reflectionWidth+'px'; | ||
113 | + d.style.height = divHeight+'px'; | ||
114 | + p.parentNode.replaceChild(d, p); | ||
115 | + | ||
116 | + d.appendChild(p); | ||
117 | + d.appendChild(canvas); | ||
118 | + | ||
119 | + context.save(); | ||
120 | + | ||
121 | + context.translate(0,image.height-1); | ||
122 | + context.scale(1,-1); | ||
123 | + | ||
124 | + context.drawImage(image, 0, 0, reflectionWidth, image.height); | ||
125 | + | ||
126 | + context.restore(); | ||
127 | + | ||
128 | + context.globalCompositeOperation = "destination-out"; | ||
129 | + var gradient = context.createLinearGradient(0, 0, 0, reflectionHeight); | ||
130 | + | ||
131 | + gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)"); | ||
132 | + gradient.addColorStop(0, "rgba(255, 255, 255, "+(1-options['opacity'])+")"); | ||
133 | + | ||
134 | + context.fillStyle = gradient; | ||
135 | + context.rect(0, 0, reflectionWidth, reflectionHeight*2); | ||
136 | + context.fill(); | ||
137 | + } | ||
138 | + } | ||
139 | + } catch (e) { | ||
140 | + } | ||
141 | + }, | ||
142 | + | ||
143 | + remove : function(image) { | ||
144 | + if (image.className == "reflected") { | ||
145 | + image.className = image.parentNode.className; | ||
146 | + image.parentNode.parentNode.replaceChild(image, image.parentNode); | ||
147 | + } | ||
148 | + } | ||
149 | +} | ||
150 | + | ||
151 | +function addReflections() { | ||
152 | + var rimages = document.myGetElementsByClassName('reflect'); | ||
153 | + for (i=0;i<rimages.length;i++) { | ||
154 | + var rheight = null; | ||
155 | + var ropacity = null; | ||
156 | + | ||
157 | + var classes = rimages[i].className.split(' '); | ||
158 | + for (j=0;j<classes.length;j++) { | ||
159 | + if (classes[j].indexOf("rheight") == 0) { | ||
160 | + var rheight = classes[j].substring(7)/100; | ||
161 | + } else if (classes[j].indexOf("ropacity") == 0) { | ||
162 | + var ropacity = classes[j].substring(8)/100; | ||
163 | + } | ||
164 | + } | ||
165 | + | ||
166 | + Reflection.add(rimages[i], { height: rheight, opacity : ropacity}); | ||
167 | + } | ||
168 | +} | ||
169 | + | ||
170 | +if (window.addEventListener) { // DOM method for binding an event | ||
171 | + window.addEventListener("load", addReflections, false); | ||
172 | +} else if (window.attachEvent) { // IE exclusive method for binding an event | ||
173 | + window.attachEvent("onload", addReflections); | ||
174 | +} else { // Support older browsers | ||
175 | + var previousOnload = window.onload; | ||
176 | + window.onload = function() { if (previousOnload) previousOnload(); addReflections(); } | ||
177 | +} |
public/stylesheets/application.css
@@ -3692,3 +3692,110 @@ h1#agenda-title { | @@ -3692,3 +3692,110 @@ h1#agenda-title { | ||
3692 | .highlights-image-link { | 3692 | .highlights-image-link { |
3693 | border: 1px solid #ccc; | 3693 | border: 1px solid #ccc; |
3694 | } | 3694 | } |
3695 | + | ||
3696 | +/* Featured Products stuff */ | ||
3697 | + | ||
3698 | +.featured-product-items { | ||
3699 | + width: 100%; | ||
3700 | + display: table; | ||
3701 | + margin: 0 auto; | ||
3702 | + text-align: center; | ||
3703 | +} | ||
3704 | + | ||
3705 | +.featured-product-items ul { | ||
3706 | + display: table-row; | ||
3707 | +} | ||
3708 | + | ||
3709 | +.featured-product-item { | ||
3710 | + list-style-type: none; | ||
3711 | + display: table-cell !important; | ||
3712 | +} | ||
3713 | + | ||
3714 | +.featured-product-item div { | ||
3715 | + margin: 0 auto; | ||
3716 | +} | ||
3717 | + | ||
3718 | +.featured-products-list { | ||
3719 | + padding: 0; | ||
3720 | +} | ||
3721 | + | ||
3722 | +.featured-product-arrow { | ||
3723 | + float: left; | ||
3724 | + width: 20px; | ||
3725 | + background-repeat: no-repeat; | ||
3726 | + height: 160px; | ||
3727 | + background-position: center 55px; | ||
3728 | +} | ||
3729 | + | ||
3730 | +.featured-product-arrow span { | ||
3731 | + display: none; | ||
3732 | +} | ||
3733 | + | ||
3734 | +.featured-product-prev { | ||
3735 | + background-image: url(/designs/icons/tango/Tango/16x16/actions/go-previous.png); | ||
3736 | +} | ||
3737 | + | ||
3738 | +.featured-product-next { | ||
3739 | + background-image: url(/designs/icons/tango/Tango/16x16/actions/go-next.png); | ||
3740 | +} | ||
3741 | + | ||
3742 | +.featured-products-block-container { | ||
3743 | + width: 92%; | ||
3744 | +} | ||
3745 | + | ||
3746 | +.box-2 .featured-products-block-container, | ||
3747 | +.box-3 .featured-products-block-container { | ||
3748 | + width: 78%; | ||
3749 | +} | ||
3750 | + | ||
3751 | +.featured-products-group { | ||
3752 | + width: 100%; | ||
3753 | + margin: 0 auto; | ||
3754 | + text-align: center; | ||
3755 | +} | ||
3756 | + | ||
3757 | +.featured-product-desc { | ||
3758 | + display: none; | ||
3759 | +} | ||
3760 | + | ||
3761 | +.featured-products-block-container, | ||
3762 | +.featured-products-group { | ||
3763 | + overflow: hidden; | ||
3764 | + float: left; | ||
3765 | + height: 160px; | ||
3766 | + position: relative; | ||
3767 | +} | ||
3768 | + | ||
3769 | +.featured-products-group ul { | ||
3770 | + padding: 0; | ||
3771 | + padding-left: 4px; | ||
3772 | +} | ||
3773 | + | ||
3774 | +.featured-products-footer { | ||
3775 | + clear: both; | ||
3776 | +} | ||
3777 | + | ||
3778 | +.featured-product-info { | ||
3779 | + position: absolute; | ||
3780 | + top: 0; | ||
3781 | + z-index: 9999; | ||
3782 | + height: 125px; | ||
3783 | + overflow: hidden; | ||
3784 | + font-size: 11px; | ||
3785 | + background-color: #fff; | ||
3786 | + opacity: 0.7; | ||
3787 | + border: 1px solid #333; | ||
3788 | + padding: 5px; | ||
3789 | + text-align: left; | ||
3790 | +} | ||
3791 | + | ||
3792 | +.box-2 .featured-product-info, | ||
3793 | +.box-3 .featured-product-info { | ||
3794 | + width: 110px; | ||
3795 | + margin-left: 50%; | ||
3796 | + left: -60px; | ||
3797 | +} | ||
3798 | + | ||
3799 | +#content .featured-product-info h3 { | ||
3800 | + font-size: 11px; | ||
3801 | +} |
test/functional/environment_design_controller_test.rb
@@ -6,7 +6,7 @@ class EnvironmentDesignController; def rescue_action(e) raise e end; end | @@ -6,7 +6,7 @@ class EnvironmentDesignController; def rescue_action(e) raise e end; end | ||
6 | 6 | ||
7 | class EnvironmentDesignControllerTest < Test::Unit::TestCase | 7 | class EnvironmentDesignControllerTest < Test::Unit::TestCase |
8 | 8 | ||
9 | - ALL_BLOCKS = [ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock ] | 9 | + ALL_BLOCKS = [ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock ] |
10 | 10 | ||
11 | def setup | 11 | def setup |
12 | @controller = EnvironmentDesignController.new | 12 | @controller = EnvironmentDesignController.new |
test/functional/profile_design_controller_test.rb
@@ -10,7 +10,7 @@ class ProfileDesignControllerTest < Test::Unit::TestCase | @@ -10,7 +10,7 @@ class ProfileDesignControllerTest < Test::Unit::TestCase | ||
10 | PERSON_BLOCKS_WITH_MEMBERS = PERSON_BLOCKS + [MembersBlock] | 10 | PERSON_BLOCKS_WITH_MEMBERS = PERSON_BLOCKS + [MembersBlock] |
11 | PERSON_BLOCKS_WITH_BLOG = PERSON_BLOCKS + [BlogArchivesBlock] | 11 | PERSON_BLOCKS_WITH_BLOG = PERSON_BLOCKS + [BlogArchivesBlock] |
12 | 12 | ||
13 | - ENTERPRISE_BLOCKS = COMMOM_BLOCKS + [DisabledEnterpriseMessageBlock, HighlightsBlock] | 13 | + ENTERPRISE_BLOCKS = COMMOM_BLOCKS + [DisabledEnterpriseMessageBlock, HighlightsBlock, FeaturedProductsBlock] |
14 | ENTERPRISE_BLOCKS_WITH_PRODUCTS_ENABLE = ENTERPRISE_BLOCKS + [ProductsBlock] | 14 | ENTERPRISE_BLOCKS_WITH_PRODUCTS_ENABLE = ENTERPRISE_BLOCKS + [ProductsBlock] |
15 | 15 | ||
16 | attr_reader :holder | 16 | attr_reader :holder |
test/unit/application_helper_test.rb
@@ -579,6 +579,11 @@ class ApplicationHelperTest < Test::Unit::TestCase | @@ -579,6 +579,11 @@ class ApplicationHelperTest < Test::Unit::TestCase | ||
579 | assert_equal 'filename.mp3', short_filename('filename.mp3') | 579 | assert_equal 'filename.mp3', short_filename('filename.mp3') |
580 | end | 580 | end |
581 | 581 | ||
582 | + include ActionView::Helpers::NumberHelper | ||
583 | + should 'format float to money as Brazillian currency' do | ||
584 | + assert_equal 'R$10,00', float_to_currency(10.0) | ||
585 | + end | ||
586 | + | ||
582 | protected | 587 | protected |
583 | 588 | ||
584 | def url_for(args = {}) | 589 | def url_for(args = {}) |
test/unit/enterprise_test.rb
@@ -377,4 +377,22 @@ class EnterpriseTest < Test::Unit::TestCase | @@ -377,4 +377,22 @@ class EnterpriseTest < Test::Unit::TestCase | ||
377 | ent = Enterprise.create!(:name => 'test enteprise', :identifier => 'test_ent') | 377 | ent = Enterprise.create!(:name => 'test enteprise', :identifier => 'test_ent') |
378 | assert_equal 3, ent.boxes.size | 378 | assert_equal 3, ent.boxes.size |
379 | end | 379 | end |
380 | + | ||
381 | + should 'collect the highlighted products with image' do | ||
382 | + env = Environment.default | ||
383 | + e1 = fast_create(Enterprise) | ||
384 | + p1 = e1.products.create!(:name => 'test_prod1') | ||
385 | + products = [] | ||
386 | + 3.times {|n| | ||
387 | + products.push(Product.create!(:name => "product #{n}", :enterprise_id => e1.id, :highlighted => true, :image_builder => { | ||
388 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | ||
389 | + })) | ||
390 | + } | ||
391 | + Product.create!(:name => "product 4", :enterprise_id => e1.id, :highlighted => true) | ||
392 | + Product.create!(:name => "product 5", :enterprise_id => e1.id, :image_builder => { | ||
393 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | ||
394 | + }) | ||
395 | + assert_equal products, e1.highlighted_products_with_image | ||
396 | + end | ||
397 | + | ||
380 | end | 398 | end |
test/unit/environment_test.rb
@@ -374,6 +374,23 @@ class EnvironmentTest < Test::Unit::TestCase | @@ -374,6 +374,23 @@ class EnvironmentTest < Test::Unit::TestCase | ||
374 | assert_includes env.products, p1 | 374 | assert_includes env.products, p1 |
375 | end | 375 | end |
376 | 376 | ||
377 | + should 'collect the highlighted products with image through enterprises' do | ||
378 | + env = Environment.default | ||
379 | + e1 = fast_create(Enterprise) | ||
380 | + p1 = e1.products.create!(:name => 'test_prod1') | ||
381 | + products = [] | ||
382 | + 3.times {|n| | ||
383 | + products.push(Product.create!(:name => "product #{n}", :enterprise_id => e1.id, :highlighted => true, :image_builder => { | ||
384 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | ||
385 | + })) | ||
386 | + } | ||
387 | + Product.create!(:name => "product 4", :enterprise_id => e1.id, :highlighted => true) | ||
388 | + Product.create!(:name => "product 5", :enterprise_id => e1.id, :image_builder => { | ||
389 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | ||
390 | + }) | ||
391 | + assert_equal products, env.highlighted_products_with_image | ||
392 | + end | ||
393 | + | ||
377 | should 'not have person through communities' do | 394 | should 'not have person through communities' do |
378 | env = Environment.default | 395 | env = Environment.default |
379 | com = fast_create(Community) | 396 | com = fast_create(Community) |
@@ -0,0 +1,127 @@ | @@ -0,0 +1,127 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class FeaturedProductsBlockTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + @profile = fast_create(Profile) | ||
7 | + @environment = Environment.default | ||
8 | + @environment.boxes << Box.new | ||
9 | + end | ||
10 | + attr_reader :profile | ||
11 | + | ||
12 | + should 'refer to products' do | ||
13 | + products = [] | ||
14 | + 3.times {|n| products.push(Product.create!(:name => "product #{n}", :enterprise_id => profile.id)) } | ||
15 | + featured_products_block = FeaturedProductsBlock.create!(:product_ids => products.map(&:id)) | ||
16 | + assert_equal products, featured_products_block.products | ||
17 | + end | ||
18 | + | ||
19 | + should "have method products_for_selection" do | ||
20 | + block = FeaturedProductsBlock.new | ||
21 | + assert_respond_to block, 'products_for_selection' | ||
22 | + end | ||
23 | + | ||
24 | + should " the defaul product_ids be an empty array" do | ||
25 | + block = FeaturedProductsBlock.new | ||
26 | + assert_equal [], block.product_ids | ||
27 | + end | ||
28 | + | ||
29 | + should " the defaul groups_of be 3" do | ||
30 | + block = FeaturedProductsBlock.new | ||
31 | + assert_equal 3, block.groups_of | ||
32 | + end | ||
33 | + | ||
34 | + should 'default interval between transitions is 1000 miliseconds' do | ||
35 | + block = FeaturedProductsBlock.new | ||
36 | + assert_equal 1000, block.speed | ||
37 | + end | ||
38 | + | ||
39 | + should "reflect by default" do | ||
40 | + block = FeaturedProductsBlock.new | ||
41 | + assert_equal true, block.reflect | ||
42 | + end | ||
43 | + | ||
44 | + should 'describe itself' do | ||
45 | + assert_not_equal Block.description, FeaturedProductsBlock.description | ||
46 | + end | ||
47 | + | ||
48 | + should "the groups_of variabe be a integer" do | ||
49 | + block = FeaturedProductsBlock.new | ||
50 | + assert_kind_of Integer, block.groups_of | ||
51 | + block.groups_of = 2 | ||
52 | + block.save | ||
53 | + block.reload | ||
54 | + assert_kind_of Integer, block.groups_of | ||
55 | + block.groups_of = '2' | ||
56 | + block.save | ||
57 | + block.reload | ||
58 | + assert_kind_of Integer, block.groups_of | ||
59 | + end | ||
60 | + | ||
61 | + should "an environment block collect product automatically" do | ||
62 | + block = FeaturedProductsBlock.new() | ||
63 | + block.product_ids = [] | ||
64 | + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) | ||
65 | + 3.times {|n| | ||
66 | + Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :highlighted => true, :image_builder => { | ||
67 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | ||
68 | + }) | ||
69 | + } | ||
70 | + @environment.boxes.first.blocks<< block | ||
71 | + | ||
72 | + assert_not_equal [], block.product_ids | ||
73 | + end | ||
74 | + | ||
75 | + should "an environment block collect just product with image automatically" do | ||
76 | + block = FeaturedProductsBlock.new() | ||
77 | + block.product_ids = [] | ||
78 | + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) | ||
79 | + 3.times {|n| | ||
80 | + Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :highlighted => true) | ||
81 | + } | ||
82 | + @environment.boxes.first.blocks<< block | ||
83 | + | ||
84 | + assert_equal [], block.product_ids | ||
85 | + end | ||
86 | + | ||
87 | + should "an environment block collect just highlighted product automatically" do | ||
88 | + block = FeaturedProductsBlock.new() | ||
89 | + block.product_ids = [] | ||
90 | + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) | ||
91 | + 3.times {|n| | ||
92 | + Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :image_builder => { | ||
93 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | ||
94 | + }) | ||
95 | + } | ||
96 | + @environment.boxes.first.blocks<< block | ||
97 | + | ||
98 | + assert_equal [], block.product_ids | ||
99 | + end | ||
100 | + | ||
101 | + should 'display feature products block' do | ||
102 | + block = FeaturedProductsBlock.new | ||
103 | + | ||
104 | + self.expects(:render).with(:file => 'blocks/featured_products', :locals => { :block => block}) | ||
105 | + instance_eval(& block.content) | ||
106 | + end | ||
107 | + | ||
108 | + should "return just highlighted products with image for selection" do | ||
109 | + block = FeaturedProductsBlock.new() | ||
110 | + block.product_ids = [] | ||
111 | + enterprise = Enterprise.create!(:name => "My enterprise", :identifier => 'myenterprise', :environment => @environment) | ||
112 | + products = [] | ||
113 | + 3.times {|n| | ||
114 | + products.push(Product.create!(:name => "product #{n}", :enterprise_id => enterprise.id, :highlighted => true, :image_builder => { | ||
115 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | ||
116 | + })) | ||
117 | + } | ||
118 | + Product.create!(:name => "product 4", :enterprise_id => enterprise.id, :highlighted => true) | ||
119 | + Product.create!(:name => "product 5", :enterprise_id => enterprise.id, :image_builder => { | ||
120 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | ||
121 | + }) | ||
122 | + @environment.boxes.first.blocks<< block | ||
123 | + | ||
124 | + assert_equal products, block.products_for_selection | ||
125 | + end | ||
126 | + | ||
127 | +end |
test/unit/highlights_block_test.rb
@@ -119,12 +119,14 @@ class HighlightsBlockTest < ActiveSupport::TestCase | @@ -119,12 +119,14 @@ class HighlightsBlockTest < ActiveSupport::TestCase | ||
119 | i1 = {:image_id => 1, :address => '/address', :position => 3, :title => 'address'} | 119 | i1 = {:image_id => 1, :address => '/address', :position => 3, :title => 'address'} |
120 | i2 = {:image_id => 2, :address => '/address', :position => 1, :title => 'address'} | 120 | i2 = {:image_id => 2, :address => '/address', :position => 1, :title => 'address'} |
121 | i3 = {:image_id => 3, :address => '/address', :position => 2, :title => 'address'} | 121 | i3 = {:image_id => 3, :address => '/address', :position => 2, :title => 'address'} |
122 | - block.images = [i1,i2,i3] | 122 | + i4 = {:image_id => 4, :address => '/address', :position => 5, :title => 'address'} |
123 | + i5 = {:image_id => 5, :address => '/address', :position => 4, :title => 'address'} | ||
124 | + block.images = [i1,i2,i3,i4,i5] | ||
123 | block.shuffle = true | 125 | block.shuffle = true |
124 | block.save! | 126 | block.save! |
125 | block.reload | 127 | block.reload |
126 | - assert_equal [i1,i2,i3], block.images | ||
127 | - assert_not_equal [i2,i3,i1], block.featured_images | 128 | + assert_equal [i1,i2,i3,i4,i5], block.images |
129 | + assert_not_equal [i2,i3,i1,i4,i5], block.featured_images | ||
128 | end | 130 | end |
129 | 131 | ||
130 | end | 132 | end |