Commit ffbf0914d4ca1302cbc00175b4b73b84d9ddb144

Authored by Daniela Feitosa
2 parents a508d544 5cd7e54d

Merge branch 'AI2943_container_block_fixes' into 'stable'

Ai2943 Container Block Fixes

Fix broken edition for container block with the new css for sideboxes view.
app/controllers/box_organizer_controller.rb
... ... @@ -70,7 +70,7 @@ class BoxOrganizerController < ApplicationController
70 70 else
71 71 @center_block_types = (Box.acceptable_center_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => 1)
72 72 @side_block_types = (Box.acceptable_side_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => [2,3])
73   - @boxes = boxes_holder.boxes
  73 + @boxes = boxes_holder.boxes.with_position
74 74 render :action => 'add_block', :layout => false
75 75 end
76 76 end
... ...
app/helpers/boxes_helper.rb
... ... @@ -39,7 +39,7 @@ module BoxesHelper
39 39 end
40 40  
41 41 def display_boxes(holder, main_content)
42   - boxes = holder.boxes.first(holder.boxes_limit)
  42 + boxes = holder.boxes.with_position.first(holder.boxes_limit)
43 43 content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n")
44 44 content = main_content if (content.blank?)
45 45  
... ...
app/models/box.rb
... ... @@ -5,6 +5,8 @@ class Box < ActiveRecord::Base
5 5  
6 6 include Noosfero::Plugin::HotSpot
7 7  
  8 + named_scope :with_position, :conditions => ['boxes.position > 0']
  9 +
8 10 def environment
9 11 owner ? (owner.kind_of?(Environment) ? owner : owner.environment) : nil
10 12 end
... ...
plugins/container_block/lib/container_block_plugin.rb
... ... @@ -16,4 +16,8 @@ class ContainerBlockPlugin < Noosfero::Plugin
16 16 true
17 17 end
18 18  
  19 + def js_files
  20 + 'container_block.js'
  21 + end
  22 +
19 23 end
... ...
plugins/container_block/lib/container_block_plugin/container_block.rb
... ... @@ -7,6 +7,16 @@ class ContainerBlockPlugin::ContainerBlock < Block
7 7 settings_items :container_box_id, :type => Integer, :default => nil
8 8 settings_items :children_settings, :type => Hash, :default => {}
9 9  
  10 + validate :no_cyclical_reference, :if => 'container_box_id.present?'
  11 +
  12 + def no_cyclical_reference
  13 + errors.add(:box_id, _('cyclical reference is not allowed.')) if box_id == container_box_id
  14 + end
  15 +
  16 + before_save do |b|
  17 + raise "cyclical reference is not allowed" if b.box_id == b.container_box_id && !b.container_box_id.blank?
  18 + end
  19 +
10 20 def self.description
11 21 _('Container')
12 22 end
... ... @@ -15,6 +25,10 @@ class ContainerBlockPlugin::ContainerBlock < Block
15 25 _('This block acts as a container for another blocks')
16 26 end
17 27  
  28 + def cacheable?
  29 + false
  30 + end
  31 +
18 32 def layout_template
19 33 nil
20 34 end
... ... @@ -24,8 +38,9 @@ class ContainerBlockPlugin::ContainerBlock < Block
24 38 end
25 39  
26 40 def create_box
27   - box = Box.create!(:owner => owner)
28   - settings[:container_box_id] = box.id
  41 + container_box = Box.create!(:owner => owner)
  42 + container_box.update_attribute(:position, nil)
  43 + settings[:container_box_id] = container_box.id
29 44 save!
30 45 end
31 46  
... ...
plugins/container_block/public/container_block.js 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +function enableMoveContainerChildren(container, box) {
  2 + var div = jQuery('#box-'+box+' > .block-outer > .block');
  3 + if(!div.is('.ui-resizable')) {
  4 + div.resizable({
  5 + handles: 'e, w',
  6 + containment: '#block-'+container+' .block-inner-2',
  7 + resize: function( event, ui ) {
  8 + ui.element.height('auto');
  9 + }
  10 + });
  11 + }
  12 +}
  13 +
  14 +function disableMoveContainerChildren(container, box) {
  15 + var div = jQuery('#box-'+box+' > .block-outer > .block');
  16 + if(div.is('.ui-resizable')) {
  17 + div.resizable('destroy');
  18 + }
  19 +}
  20 +
  21 +function containerChildrenWidth(container, box) {
  22 + widths = "";
  23 + jQuery('#box-'+box+' > .block-outer > .block').each(function(i) {
  24 + childId = jQuery(this).attr('id').match(/block-(\d+)/)[1];
  25 + widths+=childId+","+jQuery(this).width()+"|";
  26 + });
  27 + return "widths="+widths;
  28 +}
... ...
plugins/container_block/public/style.css
  1 +#box-organizer .container-block-plugin_container-block > .block-inner-1 > .block-inner-2 > .button-bar {
  2 + height: 22px;
  3 + padding-bottom: 0px;
  4 + width: auto;
  5 +}
  6 +
1 7 #content .boxes .container-block-plugin_container-block .container_block_child, .container-block-plugin_container-block .block-outer {
2 8 display: inline-block;
3 9 vertical-align: top;
... ... @@ -17,14 +23,10 @@
17 23 background-image: url(/designs/icons/default/Tango/16x16/actions/go-previous.png);
18 24 }
19 25  
20   -#content .boxes .container-block-plugin_container-block .block {
21   - outline-offset: -2px;
22   -}
23   -
24 26 #content .boxes .container-block-plugin_container-block .block .ui-resizable-handle {
25 27 width: 10px;
26 28 height: 28px;
27   - z-index: 0;
  29 + z-index: 1000;
28 30 }
29 31  
30 32 #content .boxes .container-block-plugin_container-block .block .ui-resizable-e {
... ... @@ -37,6 +39,21 @@
37 39 background-image: url(/plugins/container_block/images/handle_w.png);
38 40 }
39 41  
40   -.container-block-plugin_container-block .button-bar .icon-resize {
  42 +.container-block-plugin_container-block .container-block-button-bar .icon-resize {
41 43 background-image: url(/designs/icons/default/Tango/16x16/actions/view-fullscreen.png);
42 44 }
  45 +
  46 +#box-organizer .block .container-block-button-bar {
  47 + right: 0px;
  48 + bottom: 0px;
  49 + height: auto;
  50 +}
  51 +
  52 +#box-organizer .container-block-plugin_container-block:hover .block {
  53 + outline: 1px dashed black;
  54 + outline-offset: -1px;
  55 +}
  56 +
  57 +.container-block-plugin_container-block .block-target {
  58 + background: #afd;
  59 +}
... ...
plugins/container_block/test/functional/container_block_home_controller_test.rb
... ... @@ -31,6 +31,13 @@ class HomeControllerTest < ActionController::TestCase
31 31 assert_tag :div, :attributes => { :class => 'block container-block-plugin_container-block' }
32 32 end
33 33  
  34 + should 'display block title' do
  35 + @block.title = "Block Title"
  36 + @block.save!
  37 + get :index
  38 + assert_tag :div, :attributes => { :class => 'block container-block-plugin_container-block' }, :descendant => {:tag => 'h3', :attributes => { :class => "block-title"}, :content => @block.title }
  39 + end
  40 +
34 41 should 'display container children' do
35 42 c1 = RawHTMLBlock.create!(:box => @block.container_box, :html => 'child1 content')
36 43 c2 = RawHTMLBlock.create!(:box => @block.container_box, :html => 'child2 content')
... ...
plugins/container_block/test/unit/block_test.rb
... ... @@ -1,31 +0,0 @@
1   -require 'test_helper'
2   -
3   -class BlockTest < ActiveSupport::TestCase
4   -
5   - def setup
6   - @environment = fast_create(Environment)
7   - @box = Box.create!(:owner => @environment)
8   - @container = ContainerBlockPlugin::ContainerBlock.create!(:box => @box)
9   - end
10   -
11   - should 'return environment box if block owner is not a ContainerBlock' do
12   - block = Block.create!(:box => @box)
13   - assert_equal @box, block.box
14   - end
15   -
16   - should 'return container box if block owner is a ContainerBlock' do
17   - block = Block.create!(:box => @container.container_box)
18   - assert_equal @container.container_box, block.box
19   - end
20   -
21   - should 'return block owner if block onwer is not a ContainerBlock' do
22   - block = Block.create!(:box => @box)
23   - assert_equal @environment, block.owner
24   - end
25   -
26   - should 'return environment as owner if block onwer is a ContainerBlock' do
27   - block = Block.create!(:box => @container.container_box)
28   - assert_equal @environment, block.owner
29   - end
30   -
31   -end
plugins/container_block/test/unit/container_block_plugin/container_block_test.rb
... ... @@ -20,6 +20,11 @@ class ContainerBlockPlugin::ContainerBlockTest &lt; ActiveSupport::TestCase
20 20 assert @block.container_box_id
21 21 end
22 22  
  23 + should 'created box should have nil as position' do
  24 + @block.save!
  25 + assert_equal nil, @block.container_box.position
  26 + end
  27 +
23 28 should 'return created box' do
24 29 @block.save!
25 30 assert @block.container_box
... ... @@ -89,4 +94,27 @@ class ContainerBlockPlugin::ContainerBlockTest &lt; ActiveSupport::TestCase
89 94 end
90 95 end
91 96  
  97 + should 'not mess up with boxes positions when destroyed' do
  98 + env = fast_create(Environment)
  99 + box1 = fast_create(Box, :owner_id => env.id, :owner_type => 'Environment', :position => 1)
  100 + box2 = fast_create(Box, :owner_id => env.id, :owner_type => 'Environment', :position => 2)
  101 + box3 = fast_create(Box, :owner_id => env.id, :owner_type => 'Environment', :position => 3)
  102 + block = ContainerBlockPlugin::ContainerBlock.create!(:box => box1)
  103 + block.destroy
  104 + assert_equal [1, 2, 3], [box1.reload.position, box2.reload.position, box3.reload.position]
  105 + end
  106 +
  107 + should 'be able to change box' do
  108 + @block.save!
  109 + @block.box = Box.new(:owner => Environment.default)
  110 + @block.save!
  111 + end
  112 +
  113 + should 'not able to change box to be the same as container_box' do
  114 + @block.save!
  115 + @block.box = @block.container_box
  116 + @block.save
  117 + assert @block.errors.invalid?(:box_id)
  118 + end
  119 +
92 120 end
... ...
plugins/container_block/test/unit/environment_test.rb
... ... @@ -1,32 +0,0 @@
1   -require 'test_helper'
2   -
3   -class EnvironmentTest < ActiveSupport::TestCase
4   -
5   - def setup
6   - @environment = fast_create(Environment)
7   -
8   - @box = Box.create!(:owner => @environment)
9   - @block = Block.create!(:box => @box)
10   -
11   - @container = ContainerBlockPlugin::ContainerBlock.create!(:box => @box)
12   - end
13   -
14   - should 'return blocks as usual' do
15   - assert_equal [@block, @container], @environment.blocks
16   - end
17   -
18   - should 'return blocks with container children' do
19   - child = Block.create!(:box => @container.container_box)
20   - assert_equal [@block, @container, child], @environment.blocks
21   - end
22   -
23   - should 'return block with id at find method' do
24   - assert_equal @block, @environment.blocks.find(@block.id)
25   - end
26   -
27   - should 'return child block with id at find method' do
28   - child = Block.create!(:box => @container.container_box)
29   - assert_equal child, @environment.blocks.find(child.id)
30   - end
31   -
32   -end
plugins/container_block/test/unit/profile_test.rb
... ... @@ -1,32 +0,0 @@
1   -require 'test_helper'
2   -
3   -class ProfileTest < ActiveSupport::TestCase
4   -
5   - def setup
6   - @profile = fast_create(Profile)
7   -
8   - @box = Box.create!(:owner => @profile)
9   - @block = Block.create!(:box => @box)
10   -
11   - @container = ContainerBlockPlugin::ContainerBlock.create!(:box => @box)
12   - end
13   -
14   - should 'return blocks as usual' do
15   - assert_equal [@block, @container], @profile.blocks
16   - end
17   -
18   - should 'return blocks with container children' do
19   - child = Block.create!(:box => @container.container_box)
20   - assert_equal [@block, @container, child], @profile.blocks
21   - end
22   -
23   - should 'return block with id at find method' do
24   - assert_equal @block, @profile.blocks.find(@block.id)
25   - end
26   -
27   - should 'return child block with id at find method' do
28   - child = Block.create!(:box => @container.container_box)
29   - assert_equal child, @profile.blocks.find(child.id)
30   - end
31   -
32   -end
plugins/container_block/views/blocks/container.rhtml
1 1 <% edit_mode = @controller.send(:boxes_editor?) && @controller.send(:uses_design_blocks?) %>
2 2 <% box_decorator = edit_mode ? self : BoxesHelper::DontMoveBlocks %>
3 3  
  4 +<%= block_title(block.title) %>
4 5  
5 6 <div class="box" id="box-<%= block.container_box.id %>">
6 7 <%= display_box_content(block.container_box, nil) %>
... ... @@ -15,8 +16,18 @@
15 16 </style>
16 17  
17 18 <% if edit_mode %>
18   - <div class="button-bar">
19   - <a href="#" onclick="toggleMoveContainerChildren(<%= block.id %>, <%= block.container_box.id %>); return false;" class="button icon-resize" title=<%= _('Resize blocks').to_json %>></a>
  19 +
  20 + <script>
  21 + jQuery("#block-<%= block.id %>").hover(
  22 + function() {
  23 + enableMoveContainerChildren(<%= block.id %>, <%= block.container_box.id %>);
  24 + }, function() {
  25 + disableMoveContainerChildren(<%= block.id %>, <%= block.container_box.id %>);
  26 + }
  27 + );
  28 + </script>
  29 +
  30 + <div class="container-block-button-bar button-bar">
20 31 <%= link_to_remote '', :url => { :controller => @controller.boxes_holder.kind_of?(Environment) ? 'container_block_plugin_admin' : 'container_block_plugin_myprofile', :action => 'saveWidths', :id => block.id },
21 32 :with => "containerChildrenWidth(#{block.id}, #{block.container_box.id})",
22 33 :html => {:class => "button icon-save container_block_save", :id => "container_block_save_#{block.id}", :title => _('Save') },
... ... @@ -24,37 +35,4 @@
24 35 :loaded => "close_loading();",
25 36 :complete => "display_notice(request.responseText);"%>
26 37 </div>
27   -
28   - <script>
29   - function toggleMoveContainerChildren(container, box) {
30   - var div = jQuery('#box-'+box+' > .block-outer > .block');
31   - var targetDiv = jQuery('#box-'+box+' .block-outer .block-target');
32   - if(div.is('.ui-resizable')) {
33   - targetDiv.show();
34   - div.find("a").die("click");
35   - div.resizable('destroy');
36   - } else {
37   - targetDiv.hide();
38   - div.find("a").live("click", function(e) {
39   - e.preventDefault();
40   - });
41   - div.resizable({
42   - handles: 'e, w',
43   - containment: '#block-'+container+' .block-inner-2',
44   - resize: function( event, ui ) {
45   - ui.element.height('auto');
46   - }
47   - });
48   - }
49   - }
50   -
51   - function containerChildrenWidth(container, box) {
52   - widths = "";
53   - jQuery('#box-'+box+' > .block-outer > .block').each(function(i) {
54   - childId = jQuery(this).attr('id').match(/block-(\d+)/)[1];
55   - widths+=childId+","+jQuery(this).width()+"|";
56   - });
57   - return "widths="+widths;
58   - }
59   - </script>
60 38 <% end %>
... ...
public/stylesheets/application.css
... ... @@ -1735,8 +1735,8 @@ a.button.disabled, input.disabled {
1735 1735 display: none;
1736 1736 }
1737 1737  
1738   -#box-organizer .block:focus .button-bar,
1739   -#box-organizer .block:hover .button-bar {
  1738 +#box-organizer .block-outer:focus .button-bar,
  1739 +#box-organizer .block-outer:hover .button-bar {
1740 1740 display: block;
1741 1741 }
1742 1742  
... ...
test/unit/box_test.rb
... ... @@ -140,4 +140,11 @@ class BoxTest &lt; ActiveSupport::TestCase
140 140 assert !blocks.include?('box-test_plugin-block')
141 141 end
142 142  
  143 + should 'list only boxes with a postion greater than zero' do
  144 + profile = fast_create(Profile)
  145 + box = fast_create(Box, :owner_id => profile.id, :owner_type => 'Profile', :position => 0)
  146 + box2 = fast_create(Box, :owner_id => profile.id, :owner_type => 'Profile', :position => 1)
  147 + assert_equal [box2], profile.boxes.with_position
  148 + end
  149 +
143 150 end
... ...
test/unit/boxes_helper_test.rb
... ... @@ -13,7 +13,8 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase
13 13  
14 14 should 'include profile-specific header' do
15 15 holder = mock
16   - holder.stubs(:boxes).returns([])
  16 + holder.stubs(:boxes).returns(boxes = [])
  17 + boxes.stubs(:with_position).returns([])
17 18 holder.stubs(:boxes_limit).returns(0)
18 19 holder.stubs(:custom_header_expanded).returns('my custom header')
19 20 @controller.stubs(:boxes_holder).returns(holder)
... ... @@ -23,7 +24,8 @@ class BoxesHelperTest &lt; ActiveSupport::TestCase
23 24  
24 25 should 'include profile-specific footer' do
25 26 holder = mock
26   - holder.stubs(:boxes).returns([])
  27 + holder.stubs(:boxes).returns(boxes = [])
  28 + boxes.stubs(:with_position).returns([])
27 29 holder.stubs(:boxes_limit).returns(0)
28 30 holder.stubs(:custom_footer_expanded).returns('my custom footer')
29 31 @controller.stubs(:boxes_holder).returns(holder)
... ...