Commit a86306b1acc9b945fb1c5c33015724a1487b9fac

Authored by Michel Felipe
1 parent d877a56d

New feature archive articles to avoid create comments, associate children articles and perform votes

app/controllers/my_profile/cms_controller.rb
... ... @@ -99,6 +99,7 @@ class CmsController < MyProfileController
99 99 @article.image.save!
100 100 end
101 101 @article.last_changed_by = user
  102 + @article.old_parent_id = @article.parent_id
102 103 if @article.update_attributes(params[:article])
103 104 if !continue
104 105 if @article.content_type.nil? || @article.image?
... ...
app/helpers/article_helper.rb
... ... @@ -15,6 +15,13 @@ module ArticleHelper
15 15 topic_creation(@article) +
16 16 content_tag('h4', _('Options')) +
17 17 content_tag('div',
  18 + content_tag('div',
  19 + check_box(:article, :archived) +
  20 + content_tag('span', ' ', :class => 'access-archived-icon') +
  21 + content_tag('label', _('Read Only'), :for => 'article_archived_true') +
  22 + content_tag('span', _('Archive to avoid create comments, votes, actions in children articles...'), :class => 'access-note'),
  23 + :class => 'access-item'
  24 + ) +
18 25 (article.profile.has_members? ?
19 26 content_tag(
20 27 'div',
... ... @@ -63,13 +70,20 @@ module ArticleHelper
63 70 content_tag('div',
64 71 content_tag('div',
65 72 radio_button(:article, :published, true) +
66   - content_tag('label', _('Public (visible to other people)'), :for => 'article_published_true')
  73 + content_tag('span', ' ', :class => 'access-public-icon') +
  74 + content_tag('label', _('Public'), :for => 'article_published_true') +
  75 + content_tag('span', _('Visible to other people'), :class => 'access-note'),
  76 + :class => 'access-item'
67 77 ) +
68 78 content_tag('div',
69 79 radio_button(:article, :published, false) +
70   - content_tag('label', _('Private'), :for => 'article_published_false', :id => "label_private")
  80 + content_tag('span', ' ', :class => 'access-private-icon') +
  81 + content_tag('label', _('Private'), :for => 'article_published_false', :id => "label_private") +
  82 + content_tag('span', _('Limit visibility of this article'), :class => 'access-note'),
  83 + :class => 'access-item'
71 84 ) +
72   - privacity_exceptions(article, tokenized_children)
  85 + privacity_exceptions(article, tokenized_children),
  86 + :class => 'access-itens'
73 87 )
74 88 end
75 89  
... ...
app/helpers/folder_helper.rb
... ... @@ -61,7 +61,15 @@ module FolderHelper
61 61 @article = article
62 62  
63 63 visibility_options(article,tokenized_children) +
  64 + content_tag('h4', _('Options')) +
64 65 content_tag('div',
  66 + content_tag('div',
  67 + check_box(:article, :archived) +
  68 + content_tag('span', ' ', :class => 'access-archived-icon') +
  69 + content_tag('label', _('Read Only'), :for => 'article_archived_true') +
  70 + content_tag('span', _('Archive to avoid votes and create new children articles'), :class => 'access-note'),
  71 + :class => 'access-item'
  72 + ) +
65 73 hidden_field_tag('article[accept_comments]', 0)
66 74 )
67 75 end
... ...
app/models/article.rb
... ... @@ -9,7 +9,9 @@ class Article < ActiveRecord::Base
9 9 :highlighted, :notify_comments, :display_hits, :slug,
10 10 :external_feed_builder, :display_versions, :external_link,
11 11 :image_builder, :show_to_followers,
12   - :author, :display_preview
  12 + :author, :display_preview, :archived
  13 +
  14 + attr_accessor :old_parent_id
13 15  
14 16 acts_as_having_image
15 17  
... ... @@ -154,6 +156,8 @@ class Article < ActiveRecord::Base
154 156 validate :no_self_reference
155 157 validate :no_cyclical_reference, :if => 'parent_id.present?'
156 158  
  159 + validate :parent_archived?
  160 +
157 161 def no_self_reference
158 162 errors.add(:parent_id, _('self-reference is not allowed.')) if id && parent_id == id
159 163 end
... ... @@ -484,6 +488,10 @@ class Article < ActiveRecord::Base
484 488 end
485 489 end
486 490  
  491 + def archived?
  492 + (self.parent && self.parent.archived) || self.archived
  493 + end
  494 +
487 495 def self.folder_types
488 496 ['Folder', 'Blog', 'Forum', 'Gallery']
489 497 end
... ... @@ -842,4 +850,10 @@ class Article < ActiveRecord::Base
842 850 sanitizer.sanitize(text)
843 851 end
844 852  
  853 + def parent_archived?
  854 + if (self.old_parent_id != self.parent_id) && self.parent && self.parent.archived?
  855 + errors.add(:parent_folder, N_('is archived!!'))
  856 + end
  857 + end
  858 +
845 859 end
... ...
app/models/comment.rb
... ... @@ -210,4 +210,8 @@ class Comment < ActiveRecord::Base
210 210 user.present? && user == author
211 211 end
212 212  
  213 + def archived?
  214 + self.article.archived?
  215 + end
  216 +
213 217 end
... ...
app/models/folder.rb
... ... @@ -65,4 +65,8 @@ class Folder < Article
65 65 !self.has_posts? || self.gallery?
66 66 end
67 67  
  68 + def archived?
  69 + self.archived
  70 + end
  71 +
68 72 end
... ...
app/views/cms/_archived_warning.html.erb 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<% if !article.errors.any? %>
  2 + <div class="text-warning">
  3 + <p>
  4 + <i class="icon"></i>
  5 + <%= _("Archived article! It's read-only") %>
  6 + </p>
  7 + </div>
  8 +<% end %>
... ...
app/views/cms/edit.html.erb
1 1 <%= error_messages_for 'article' %>
2 2  
  3 +<% if @article.archived? %>
  4 + <%= render :partial => 'archived_warning', :locals => {:article => @article} %>
  5 +<% end %>
3 6 <div class='<%= (@article.display_media_panel? ? 'with_media_panel' : 'no_media_panel') %>'>
4 7 <%= labelled_form_for 'article', :html => { :multipart => true, :class => @type } do |f| %>
5 8  
... ... @@ -9,6 +12,7 @@
9 12  
10 13 <%= hidden_field_tag('success_back_to', @success_back_to) %>
11 14  
  15 +
12 16 <%= render :partial => partial_for_class(@article.class), :locals => { :f => f } %>
13 17  
14 18 <% if environment.is_portal_community?(profile) %>
... ...
app/views/content_viewer/_article_toolbar.html.erb
... ... @@ -29,7 +29,9 @@
29 29 <%= expirable_button @page, :locale, content, url %>
30 30 <% end %>
31 31  
32   - <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:new, @page) %>
  32 + <% if !@page.archived? %>
  33 + <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:new, @page) %>
  34 + <% end %>
33 35  
34 36 <% content = content_tag('span', label_for_clone_article(@page)) %>
35 37 <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :parent_id => (@page.folder? ? @page : @page.parent), :type => @page.class}) %>
... ... @@ -64,6 +66,9 @@
64 66 <% end %>
65 67 <%= button_without_text(:feed, _('RSS feed'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
66 68 <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
  69 + <% if @page.archived? %>
  70 + <%= render :partial => 'cms/archived_warning', :locals => {:article => @page} %>
  71 + <% end %>
67 72 <%= render :partial => 'article_title', :locals => {:no_link => true} %>
68 73 <%= article_translations(@page) %>
69 74 </div>
... ...
app/views/content_viewer/view_page.html.erb
... ... @@ -85,7 +85,7 @@
85 85 <% end %>
86 86 </ul>
87 87  
88   - <% if @page.accept_comments? %>
  88 + <% if !@page.archived? || @page.accept_comments? %>
89 89 <div id='page-comment-form' class='page-comment-form'><%= render :partial => 'comment/comment_form', :locals =>{:url => {:controller => :comment, :action => :create}, :display_link => true, :cancel_triggers_hide => true}%></div>
90 90 <% end %>
91 91 </div><!-- end class="comments" -->
... ...
db/migrate/20151112135709_add_archived_to_articles.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class AddArchivedToArticles < ActiveRecord::Migration
  2 + def up
  3 + add_column :articles, :archived, :boolean, :default => false
  4 + end
  5 +
  6 + def down
  7 + remove_column :articles, :archived
  8 + end
  9 +end
... ...
public/images/icons-app/article-archived-icon.png 0 → 100644

166 Bytes

public/images/icons-app/article-private-icon.png 0 → 100644

273 Bytes

public/images/icons-app/article-public-icon.png 0 → 100644

570 Bytes

public/images/icons-app/warning-icon.png 0 → 100644

509 Bytes

public/javascripts/article.js
... ... @@ -212,4 +212,10 @@ jQuery(function($) {
212 212 $("#article_published_true").click(show_hide_privacy_options);
213 213 $(".custom_privacy_option").click(show_hide_token_input);
214 214  
  215 + //Workaround to pointer-events:none CSS3
  216 + $('a.disabled').click(function(e){
  217 + e.preventDefault();
  218 + return false;
  219 + });
  220 +
215 221 });
... ...
public/stylesheets/cms.scss
1 1 @import 'cms/fetch-external-feed';
2 2 @import 'cms/media-panel';
  3 +@import 'cms/access-options';
3 4  
4 5 table.cms-articles {
5 6 table-layout: fixed;
... ...
public/stylesheets/cms/access-options.scss 0 → 100644
... ... @@ -0,0 +1,67 @@
  1 +//Variables
  2 +$icons-size: 24px;
  3 +$warning-color: #e75e40;
  4 +$description-color: #666;
  5 +$access-types: public, private, archived;
  6 +
  7 +.text-warning {
  8 + text-align: center;
  9 + color: $warning-color;
  10 + font: {
  11 + size: 15px;
  12 + weight: bold;
  13 + }
  14 +
  15 + p i.icon {
  16 + display: inline-block;
  17 + font-size: inherit;
  18 + text-rendering: auto;
  19 + background: url('images/icons-app/warning-icon.png');
  20 + vertical-align: middle;
  21 + margin-top: -5px;
  22 + width: $icons-size;
  23 + height: $icons-size;
  24 + border: none;
  25 + }
  26 +}
  27 +
  28 +#edit-article-options {
  29 +
  30 + .access-itens .access-item {
  31 + input,label {
  32 + cursor: pointer;
  33 + }
  34 + }
  35 +
  36 + .access-item {
  37 + margin: 15px 0;
  38 + label {
  39 + font: {
  40 + size: 13px;
  41 + weight: bold;
  42 + }
  43 + }
  44 + }
  45 +
  46 + @each $access_type in $access-types {
  47 + .access-#{$access_type}-icon, .access-#{$access_type}-icon {
  48 + display: inline-block;
  49 + margin-right: 5px;
  50 + width: $icons-size;
  51 + height: $icons-size;
  52 + vertical-align: middle;
  53 + background-image: url('images/icons-app/article-#{$access_type}-icon.png');
  54 + }
  55 + }
  56 +
  57 + .access-note {
  58 + display: block;
  59 + margin: 0;
  60 + color: $description-color;
  61 + margin-left: 50px;
  62 + font: {
  63 + size: 12px;
  64 + weight: normal;
  65 + }
  66 + }
  67 +}
... ...
test/functional/cms_controller_test.rb
... ... @@ -697,6 +697,34 @@ class CmsControllerTest &lt; ActionController::TestCase
697 697 end
698 698 end
699 699  
  700 + should "marks a article like archived" do
  701 + article = create(Article, :profile => profile, :name => 'test', :published => true, :archived => false)
  702 +
  703 + post :edit, :profile => profile.identifier, :id => article.id, :article => {:archived => true}
  704 + get :edit, :profile => profile.identifier, :id => article.id
  705 + assert_tag :tag => 'input', :attributes => { :type => 'checkbox', :name => 'article[archived]', :id => 'article_archived', :checked => 'checked' }
  706 +
  707 + end
  708 +
  709 + should "try add children into archived folders" do
  710 + folder = create(Folder, :profile => profile, :name => 'test', :published => true, :archived => false)
  711 + article_child = create(Article, :profile => profile, :name => 'test child', :parent_id => folder.id, :published => true, :archived => false)
  712 +
  713 + get :edit, :profile => profile.identifier, :id => folder.id
  714 + assert_tag :tag => 'input', :attributes => { :type => 'checkbox', :name => 'article[archived]', :id => 'article_archived' }
  715 +
  716 + post :edit, :profile => profile.identifier, :id => folder.id, :article => {:archived => true}
  717 +
  718 + get :edit, :profile => profile.identifier, :id => article_child.id
  719 + assert_tag :tag => 'div', :attributes => { :class => 'text-warning'}
  720 +
  721 + err = assert_raises ActiveRecord::RecordInvalid do
  722 + another_article_child = create(Article, :profile => profile, :name => 'other test child', :parent_id => folder.id, :published => true, :archived => false)
  723 + end
  724 + assert_match 'Parent folder is archived', err.message
  725 +
  726 + end
  727 +
700 728 should 'be able to add image with alignment' do
701 729 post :new, :type => 'TinyMceArticle', :profile => profile.identifier, :article => { :name => 'image-alignment', :body => "the text of the article with image <img src='#' align='right'/> right align..." }
702 730 saved = TinyMceArticle.find_by_name('image-alignment')
... ...