Commit 7eefa439e719d9e7f7d22cb26b42563253b6985e
Exists in
master
and in
29 other branches
Merge branch 'fixed-block' into 'master'
Fixed block Make a specific block fixed on a position. Only the environment admin can move and specify this option for the block https://gitlab.com/noosfero/noosfero/issues/26 See merge request !380
Showing
6 changed files
with
102 additions
and
31 deletions
Show diff stats
app/controllers/my_profile/profile_design_controller.rb
@@ -3,7 +3,16 @@ class ProfileDesignController < BoxOrganizerController | @@ -3,7 +3,16 @@ class ProfileDesignController < BoxOrganizerController | ||
3 | needs_profile | 3 | needs_profile |
4 | 4 | ||
5 | protect 'edit_profile_design', :profile | 5 | protect 'edit_profile_design', :profile |
6 | - | 6 | + |
7 | + before_filter :protect_fixed_block, :only => [:save, :move_block] | ||
8 | + | ||
9 | + def protect_fixed_block | ||
10 | + block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, '')) | ||
11 | + if block.fixed && !current_person.is_admin? | ||
12 | + render_access_denied | ||
13 | + end | ||
14 | + end | ||
15 | + | ||
7 | def available_blocks | 16 | def available_blocks |
8 | blocks = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock, LocationBlock, SlideshowBlock, ProfileSearchBlock, HighlightsBlock ] | 17 | blocks = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock, LocationBlock, SlideshowBlock, ProfileSearchBlock, HighlightsBlock ] |
9 | 18 |
app/helpers/boxes_helper.rb
@@ -170,49 +170,54 @@ module BoxesHelper | @@ -170,49 +170,54 @@ module BoxesHelper | ||
170 | else | 170 | else |
171 | "before-block-#{block.id}" | 171 | "before-block-#{block.id}" |
172 | end | 172 | end |
173 | - | ||
174 | - content_tag('div', ' ', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover') | 173 | + if block.nil? or modifiable?(block) |
174 | + content_tag('div', ' ', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover') | ||
175 | + else | ||
176 | + "" | ||
177 | + end | ||
175 | end | 178 | end |
176 | 179 | ||
177 | # makes the given block draggable so it can be moved away. | 180 | # makes the given block draggable so it can be moved away. |
178 | def block_handle(block) | 181 | def block_handle(block) |
179 | - draggable_element("block-#{block.id}", :revert => true) | 182 | + modifiable?(block) ? draggable_element("block-#{block.id}", :revert => true) : "" |
180 | end | 183 | end |
181 | 184 | ||
182 | def block_edit_buttons(block) | 185 | def block_edit_buttons(block) |
183 | buttons = [] | 186 | buttons = [] |
184 | nowhere = 'javascript: return false;' | 187 | nowhere = 'javascript: return false;' |
185 | 188 | ||
186 | - if block.first? | ||
187 | - buttons << icon_button('up-disabled', _("Can't move up anymore."), nowhere) | ||
188 | - else | ||
189 | - buttons << icon_button('up', _('Move block up'), { :action => 'move_block_up', :id => block.id }, { :method => 'post' }) | ||
190 | - end | 189 | + if modifiable?(block) |
190 | + if block.first? | ||
191 | + buttons << icon_button('up-disabled', _("Can't move up anymore."), nowhere) | ||
192 | + else | ||
193 | + buttons << icon_button('up', _('Move block up'), { :action => 'move_block_up', :id => block.id }, { :method => 'post' }) | ||
194 | + end | ||
191 | 195 | ||
192 | - if block.last? | ||
193 | - buttons << icon_button('down-disabled', _("Can't move down anymore."), nowhere) | ||
194 | - else | ||
195 | - buttons << icon_button(:down, _('Move block down'), { :action => 'move_block_down' ,:id => block.id }, { :method => 'post'}) | ||
196 | - end | 196 | + if block.last? |
197 | + buttons << icon_button('down-disabled', _("Can't move down anymore."), nowhere) | ||
198 | + else | ||
199 | + buttons << icon_button(:down, _('Move block down'), { :action => 'move_block_down' ,:id => block.id }, { :method => 'post'}) | ||
200 | + end | ||
197 | 201 | ||
198 | - holder = block.owner | ||
199 | - # move to opposite side | ||
200 | - # FIXME too much hardcoded stuff | ||
201 | - if holder.layout_template == 'default' | ||
202 | - if block.box.position == 2 # area 2, left side => move to right side | ||
203 | - buttons << icon_button('right', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[2].id.to_s, :id => block.id }, :method => 'post' ) | ||
204 | - elsif block.box.position == 3 # area 3, right side => move to left side | ||
205 | - buttons << icon_button('left', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[1].id.to_s, :id => block.id }, :method => 'post' ) | 202 | + holder = block.owner |
203 | + # move to opposite side | ||
204 | + # FIXME too much hardcoded stuff | ||
205 | + if holder.layout_template == 'default' | ||
206 | + if block.box.position == 2 # area 2, left side => move to right side | ||
207 | + buttons << icon_button('right', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[2].id.to_s, :id => block.id }, :method => 'post' ) | ||
208 | + elsif block.box.position == 3 # area 3, right side => move to left side | ||
209 | + buttons << icon_button('left', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[1].id.to_s, :id => block.id }, :method => 'post' ) | ||
210 | + end | ||
206 | end | 211 | end |
207 | - end | ||
208 | 212 | ||
209 | - if block.editable? | ||
210 | - buttons << colorbox_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id }) | ||
211 | - end | 213 | + if block.editable? |
214 | + buttons << colorbox_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id }) | ||
215 | + end | ||
212 | 216 | ||
213 | - if !block.main? | ||
214 | - buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) | ||
215 | - buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' }) | 217 | + if !block.main? |
218 | + buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) | ||
219 | + buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' }) | ||
220 | + end | ||
216 | end | 221 | end |
217 | 222 | ||
218 | if block.respond_to?(:help) | 223 | if block.respond_to?(:help) |
@@ -248,5 +253,7 @@ module BoxesHelper | @@ -248,5 +253,7 @@ module BoxesHelper | ||
248 | classes | 253 | classes |
249 | end | 254 | end |
250 | 255 | ||
251 | - | 256 | + def modifiable?(block) |
257 | + return !block.fixed || environment.admins.include?(user) | ||
258 | + end | ||
252 | end | 259 | end |
app/models/block.rb
1 | class Block < ActiveRecord::Base | 1 | class Block < ActiveRecord::Base |
2 | 2 | ||
3 | - attr_accessible :title, :display, :limit, :box_id, :posts_per_page, :visualization_format, :language, :display_user, :box | 3 | + attr_accessible :title, :display, :limit, :box_id, :posts_per_page, :visualization_format, :language, :display_user, :box, :fixed |
4 | 4 | ||
5 | # to be able to generate HTML | 5 | # to be able to generate HTML |
6 | include ActionView::Helpers::UrlHelper | 6 | include ActionView::Helpers::UrlHelper |
@@ -110,6 +110,9 @@ class Block < ActiveRecord::Base | @@ -110,6 +110,9 @@ class Block < ActiveRecord::Base | ||
110 | # * <tt>'all'</tt>: the block is always displayed | 110 | # * <tt>'all'</tt>: the block is always displayed |
111 | settings_items :language, :type => :string, :default => 'all' | 111 | settings_items :language, :type => :string, :default => 'all' |
112 | 112 | ||
113 | + # The block can be configured to be fixed. Only can be edited by environment admins | ||
114 | + settings_items :fixed, :type => :boolean, :default => false | ||
115 | + | ||
113 | # returns the description of the block, used when the user sees a list of | 116 | # returns the description of the block, used when the user sees a list of |
114 | # blocks to choose one to include in the design. | 117 | # blocks to choose one to include in the design. |
115 | # | 118 | # |
app/views/box_organizer/edit.html.erb
@@ -5,6 +5,12 @@ | @@ -5,6 +5,12 @@ | ||
5 | 5 | ||
6 | <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %> | 6 | <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %> |
7 | 7 | ||
8 | + <% if environment.admins.include?(user) %> | ||
9 | + <div class="fixed_block"> | ||
10 | + <%= labelled_check_box(_("Fixed"), "block[fixed]", value = "1", checked = @block.fixed) %> | ||
11 | + </div> | ||
12 | + <% end %> | ||
13 | + | ||
8 | <%= render :partial => partial_for_class(@block.class) %> | 14 | <%= render :partial => partial_for_class(@block.class) %> |
9 | 15 | ||
10 | <div class="display"> | 16 | <div class="display"> |
test/functional/profile_design_controller_test.rb
@@ -737,4 +737,22 @@ class ProfileDesignControllerTest < ActionController::TestCase | @@ -737,4 +737,22 @@ class ProfileDesignControllerTest < ActionController::TestCase | ||
737 | end | 737 | end |
738 | end | 738 | end |
739 | 739 | ||
740 | + test 'should forbid POST to save for fixed blocks' do | ||
741 | + block = profile.blocks.last | ||
742 | + block.fixed = true | ||
743 | + block.save! | ||
744 | + | ||
745 | + post :save, id: block.id, profile: profile.identifier | ||
746 | + assert_response :forbidden | ||
747 | + end | ||
748 | + | ||
749 | + test 'should forbid POST to move_block for fixed blocks' do | ||
750 | + block = profile.blocks.last | ||
751 | + block.fixed = true | ||
752 | + block.save! | ||
753 | + | ||
754 | + post :move_block, id: block.id, profile: profile.identifier, target: "end-of-box-#{@box3.id}" | ||
755 | + assert_response :forbidden | ||
756 | + end | ||
757 | + | ||
740 | end | 758 | end |
test/unit/boxes_helper_test.rb
1 | require File.dirname(__FILE__) + '/../test_helper' | 1 | require File.dirname(__FILE__) + '/../test_helper' |
2 | +require File.dirname(__FILE__) + '/../../app/helpers/boxes_helper' | ||
2 | 3 | ||
3 | class BoxesHelperTest < ActionView::TestCase | 4 | class BoxesHelperTest < ActionView::TestCase |
4 | 5 | ||
@@ -119,4 +120,31 @@ class BoxesHelperTest < ActionView::TestCase | @@ -119,4 +120,31 @@ class BoxesHelperTest < ActionView::TestCase | ||
119 | display_box_content(box, '') | 120 | display_box_content(box, '') |
120 | end | 121 | end |
121 | 122 | ||
123 | + should 'not show move options on block when block is fixed' do | ||
124 | + p = create_user_with_blocks | ||
125 | + | ||
126 | + b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] | ||
127 | + b.fixed = true | ||
128 | + b.save! | ||
129 | + | ||
130 | + stubs(:environment).returns(p.environment) | ||
131 | + stubs(:user).returns(p) | ||
132 | + | ||
133 | + assert_equal false, modifiable?(b) | ||
134 | + end | ||
135 | + | ||
136 | + should 'show move options on block when block is fixed and user is admin' do | ||
137 | + p = create_user_with_blocks | ||
138 | + | ||
139 | + b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] | ||
140 | + b.fixed = true | ||
141 | + b.save! | ||
142 | + | ||
143 | + p.environment.add_admin(p) | ||
144 | + | ||
145 | + stubs(:environment).returns(p.environment) | ||
146 | + stubs(:user).returns(p) | ||
147 | + | ||
148 | + assert_equal true, modifiable?(b) | ||
149 | + end | ||
122 | end | 150 | end |