Commit eafa036da33d503072710eae3e214f05b1bdee33

Authored by Rodrigo Souto
2 parents a752c502 9a1c00d4

Merge branch 'master' into api

Conflicts:
	lib/noosfero/plugin.rb
	test/unit/article_test.rb
	test/unit/person_test.rb
Showing 120 changed files with 1360 additions and 799 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 120 files displayed.

app/controllers/my_profile/cms_controller.rb
@@ -105,6 +105,11 @@ class CmsController < MyProfileController @@ -105,6 +105,11 @@ class CmsController < MyProfileController
105 end 105 end
106 end 106 end
107 end 107 end
  108 +
  109 + unless @article.kind_of?(RssFeed)
  110 + @escaped_body = CGI::escapeHTML(@article.body || '')
  111 + @escaped_abstract = CGI::escapeHTML(@article.abstract || '')
  112 + end
108 end 113 end
109 114
110 def new 115 def new
app/controllers/my_profile/friends_controller.rb
1 class FriendsController < MyProfileController 1 class FriendsController < MyProfileController
2 - 2 +
3 protect 'manage_friends', :profile 3 protect 'manage_friends', :profile
4 - 4 +
5 def index 5 def index
6 - @suggestions = profile.profile_suggestions.of_person.enabled.includes(:suggestion).limit(per_page) 6 + @suggestions = profile.suggested_profiles.of_person.enabled.includes(:suggestion).limit(per_page)
7 if is_cache_expired?(profile.manage_friends_cache_key(params)) 7 if is_cache_expired?(profile.manage_friends_cache_key(params))
8 @friends = profile.friends.paginate(:per_page => per_page, :page => params[:npage]) 8 @friends = profile.friends.paginate(:per_page => per_page, :page => params[:npage])
9 end 9 end
@@ -18,7 +18,7 @@ class FriendsController &lt; MyProfileController @@ -18,7 +18,7 @@ class FriendsController &lt; MyProfileController
18 end 18 end
19 19
20 def suggest 20 def suggest
21 - @suggestions = profile.profile_suggestions.of_person.enabled.includes(:suggestion).limit(per_page) 21 + @suggestions = profile.suggested_profiles.of_person.enabled.includes(:suggestion).limit(per_page)
22 end 22 end
23 23
24 def remove_suggestion 24 def remove_suggestion
@@ -26,13 +26,13 @@ class FriendsController &lt; MyProfileController @@ -26,13 +26,13 @@ class FriendsController &lt; MyProfileController
26 redirect_to :action => 'suggest' unless @person 26 redirect_to :action => 'suggest' unless @person
27 if @person && request.post? 27 if @person && request.post?
28 profile.remove_suggestion(@person) 28 profile.remove_suggestion(@person)
29 - @suggestions = profile.profile_suggestions.of_person.enabled.includes(:suggestion).limit(per_page) 29 + @suggestions = profile.suggested_profiles.of_person.enabled.includes(:suggestion).limit(per_page)
30 render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions, :per_page => params[:per_page] || per_page } 30 render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions, :per_page => params[:per_page] || per_page }
31 end 31 end
32 end 32 end
33 33
34 def connections 34 def connections
35 - @suggestion = profile.profile_suggestions.of_person.enabled.find_by_suggestion_id(params[:id]) 35 + @suggestion = profile.suggested_profiles.of_person.enabled.find_by_suggestion_id(params[:id])
36 if @suggestion 36 if @suggestion
37 @tags = @suggestion.tag_connections 37 @tags = @suggestion.tag_connections
38 @profiles = @suggestion.profile_connections 38 @profiles = @suggestion.profile_connections
app/controllers/my_profile/memberships_controller.rb
@@ -40,7 +40,7 @@ class MembershipsController &lt; MyProfileController @@ -40,7 +40,7 @@ class MembershipsController &lt; MyProfileController
40 end 40 end
41 41
42 def suggest 42 def suggest
43 - @suggestions = profile.profile_suggestions.of_community.enabled.includes(:suggestion).limit(per_page) 43 + @suggestions = profile.suggested_profiles.of_community.enabled.includes(:suggestion).limit(per_page)
44 end 44 end
45 45
46 def remove_suggestion 46 def remove_suggestion
@@ -49,13 +49,13 @@ class MembershipsController &lt; MyProfileController @@ -49,13 +49,13 @@ class MembershipsController &lt; MyProfileController
49 redirect_to :action => 'suggest' unless @community 49 redirect_to :action => 'suggest' unless @community
50 if @community && request.post? 50 if @community && request.post?
51 profile.remove_suggestion(@community) 51 profile.remove_suggestion(@community)
52 - @suggestions = profile.profile_suggestions.of_community.enabled.includes(:suggestion).limit(custom_per_page) 52 + @suggestions = profile.suggested_profiles.of_community.enabled.includes(:suggestion).limit(custom_per_page)
53 render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :communities_suggestions, :per_page => custom_per_page} 53 render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :communities_suggestions, :per_page => custom_per_page}
54 end 54 end
55 end 55 end
56 56
57 def connections 57 def connections
58 - @suggestion = profile.profile_suggestions.of_community.enabled.find_by_suggestion_id(params[:id]) 58 + @suggestion = profile.suggested_profiles.of_community.enabled.find_by_suggestion_id(params[:id])
59 if @suggestion 59 if @suggestion
60 @tags = @suggestion.tag_connections 60 @tags = @suggestion.tag_connections
61 @profiles = @suggestion.profile_connections 61 @profiles = @suggestion.profile_connections
app/controllers/my_profile/tasks_controller.rb
1 class TasksController < MyProfileController 1 class TasksController < MyProfileController
2 2
3 - protect 'perform_task', :profile 3 + protect [:perform_task, :view_tasks], :profile, :only => [:index]
  4 + protect :perform_task, :profile, :except => [:index]
4 5
5 def index 6 def index
6 @filter_type = params[:filter_type].presence 7 @filter_type = params[:filter_type].presence
@@ -15,6 +16,8 @@ class TasksController &lt; MyProfileController @@ -15,6 +16,8 @@ class TasksController &lt; MyProfileController
15 @failed = params ? params[:failed] : {} 16 @failed = params ? params[:failed] : {}
16 17
17 @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization? 18 @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization?
  19 +
  20 + @view_only = !current_person.has_permission?(:perform_task, profile)
18 end 21 end
19 22
20 def processed 23 def processed
@@ -46,7 +49,7 @@ class TasksController &lt; MyProfileController @@ -46,7 +49,7 @@ class TasksController &lt; MyProfileController
46 task = profile.find_in_all_tasks(id) 49 task = profile.find_in_all_tasks(id)
47 begin 50 begin
48 task.update_attributes(value[:task]) 51 task.update_attributes(value[:task])
49 - task.send(decision) 52 + task.send(decision, current_person)
50 rescue Exception => ex 53 rescue Exception => ex
51 message = "#{task.title} (#{task.requestor ? task.requestor.name : task.author_name})" 54 message = "#{task.title} (#{task.requestor ? task.requestor.name : task.author_name})"
52 failed[ex.message] ? failed[ex.message] << message : failed[ex.message] = [message] 55 failed[ex.message] ? failed[ex.message] << message : failed[ex.message] = [message]
app/controllers/public/content_viewer_controller.rb
@@ -11,6 +11,7 @@ class ContentViewerController &lt; ApplicationController @@ -11,6 +11,7 @@ class ContentViewerController &lt; ApplicationController
11 path = get_path(params[:page], params[:format]) 11 path = get_path(params[:page], params[:format])
12 12
13 @version = params[:version].to_i 13 @version = params[:version].to_i
  14 + @npage = params[:npage] || '1'
14 15
15 if path.blank? 16 if path.blank?
16 @page = profile.home_page 17 @page = profile.home_page
@@ -127,7 +128,7 @@ class ContentViewerController &lt; ApplicationController @@ -127,7 +128,7 @@ class ContentViewerController &lt; ApplicationController
127 end 128 end
128 129
129 unless @page.display_to?(user) 130 unless @page.display_to?(user)
130 - if !profile.visible? || profile.secret? || (user && user.follows?(profile)) 131 + if !profile.visible? || profile.secret? || (user && user.follows?(profile)) || user.blank?
131 render_access_denied 132 render_access_denied
132 else #!profile.public? 133 else #!profile.public?
133 private_profile_partial_parameters 134 private_profile_partial_parameters
app/helpers/application_helper.rb
@@ -1215,35 +1215,6 @@ module ApplicationHelper @@ -1215,35 +1215,6 @@ module ApplicationHelper
1215 list.sort.inject(Hash.new(0)){|h,i| h[i] += 1; h }.collect{ |x, n| [n, connector, x].join(" ") }.sort 1215 list.sort.inject(Hash.new(0)){|h,i| h[i] += 1; h }.collect{ |x, n| [n, connector, x].join(" ") }.sort
1216 end 1216 end
1217 1217
1218 - #FIXME Use time_ago_in_words instead of this method if you're using Rails 2.2+  
1219 - def time_ago_as_sentence(from_time, include_seconds = false)  
1220 - to_time = Time.now  
1221 - from_time = Time.parse(from_time.to_s)  
1222 - from_time = from_time.to_time if from_time.respond_to?(:to_time)  
1223 - to_time = to_time.to_time if to_time.respond_to?(:to_time)  
1224 - distance_in_minutes = (((to_time - from_time).abs)/60).round  
1225 - distance_in_seconds = ((to_time - from_time).abs).round  
1226 - case distance_in_minutes  
1227 - when 0..1  
1228 - return (distance_in_minutes == 0) ? _('less than a minute') : _('1 minute') unless include_seconds  
1229 - case distance_in_seconds  
1230 - when 0..4 then _('less than 5 seconds')  
1231 - when 5..9 then _('less than 10 seconds')  
1232 - when 10..19 then _('less than 20 seconds')  
1233 - when 20..39 then _('half a minute')  
1234 - when 40..59 then _('less than a minute')  
1235 - else _('1 minute')  
1236 - end  
1237 -  
1238 - when 2..44 then _('%{distance} minutes ago') % { :distance => distance_in_minutes }  
1239 - when 45..89 then _('about 1 hour ago')  
1240 - when 90..1439 then _('about %{distance} hours ago') % { :distance => (distance_in_minutes.to_f / 60.0).round }  
1241 - when 1440..2879 then _('1 day ago')  
1242 - when 2880..10079 then _('%{distance} days ago') % { :distance => (distance_in_minutes / 1440).round }  
1243 - else show_time(from_time)  
1244 - end  
1245 - end  
1246 -  
1247 def comment_balloon(options = {}, &block) 1218 def comment_balloon(options = {}, &block)
1248 wrapper = content_tag(:div, capture(&block), :class => 'comment-balloon-content') 1219 wrapper = content_tag(:div, capture(&block), :class => 'comment-balloon-content')
1249 (1..8).to_a.reverse.each { |i| wrapper = content_tag(:div, wrapper, :class => "comment-wrapper-#{i}") } 1220 (1..8).to_a.reverse.each { |i| wrapper = content_tag(:div, wrapper, :class => "comment-wrapper-#{i}") }
app/helpers/blog_helper.rb
@@ -22,7 +22,9 @@ module BlogHelper @@ -22,7 +22,9 @@ module BlogHelper
22 :param_name => 'npage', 22 :param_name => 'npage',
23 :previous_label => _('&laquo; Newer posts'), 23 :previous_label => _('&laquo; Newer posts'),
24 :next_label => _('Older posts &raquo;'), 24 :next_label => _('Older posts &raquo;'),
25 - :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"} 25 + :params => {:action=>"view_page",
  26 + :page=>articles.first.parent.path.split('/'),
  27 + :controller=>"content_viewer"}
26 }) if articles.present? && conf[:paginate] 28 }) if articles.present? && conf[:paginate]
27 content = [] 29 content = []
28 artic_len = articles.length 30 artic_len = articles.length
@@ -44,7 +46,7 @@ module BlogHelper @@ -44,7 +46,7 @@ module BlogHelper
44 end 46 end
45 47
46 def display_post(article, format = 'full') 48 def display_post(article, format = 'full')
47 - no_comments = (format == 'full') ? false : true 49 + no_comments = (format == 'full' || format == 'compact' ) ? false : true
48 title = article_title(article, :no_comments => no_comments) 50 title = article_title(article, :no_comments => no_comments)
49 method = "display_#{format.split('+')[0]}_format" 51 method = "display_#{format.split('+')[0]}_format"
50 html = send(method, FilePresenter.for(article)).html_safe 52 html = send(method, FilePresenter.for(article)).html_safe
@@ -55,8 +57,12 @@ module BlogHelper @@ -55,8 +57,12 @@ module BlogHelper
55 else 57 else
56 '<div class="post-pic" style="background-image:url('+img+')"></div>' 58 '<div class="post-pic" style="background-image:url('+img+')"></div>'
57 end 59 end
58 - end.to_s +  
59 - title + html 60 + end.to_s + title + html
  61 + end
  62 +
  63 + def display_compact_format(article)
  64 + render :file => 'content_viewer/_display_compact_format',
  65 + :locals => { :article => article, :format => "compact" }
60 end 66 end
61 67
62 def display_full_format(article) 68 def display_full_format(article)
app/helpers/comment_helper.rb
1 module CommentHelper 1 module CommentHelper
  2 + include DatesHelper
2 3
3 def article_title(article, args = {}) 4 def article_title(article, args = {})
4 title = article.title 5 title = article.title
app/helpers/content_viewer_helper.rb
@@ -2,6 +2,7 @@ module ContentViewerHelper @@ -2,6 +2,7 @@ module ContentViewerHelper
2 2
3 include BlogHelper 3 include BlogHelper
4 include ForumHelper 4 include ForumHelper
  5 + include DatesHelper
5 6
6 def display_number_of_comments(n) 7 def display_number_of_comments(n)
7 base_str = "<span class='comment-count hide'>#{n}</span>" 8 base_str = "<span class='comment-count hide'>#{n}</span>"
@@ -24,8 +25,9 @@ module ContentViewerHelper @@ -24,8 +25,9 @@ module ContentViewerHelper
24 unless args[:no_comments] || !article.accept_comments 25 unless args[:no_comments] || !article.accept_comments
25 comments = (" - %s") % link_to_comments(article) 26 comments = (" - %s") % link_to_comments(article)
26 end 27 end
  28 + date_format = show_with_right_format_date article
27 title << content_tag('span', 29 title << content_tag('span',
28 - content_tag('span', show_date(article.published_at), :class => 'date') + 30 + date_format +
29 content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') + 31 content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') +
30 content_tag('span', comments, :class => 'comments'), 32 content_tag('span', comments, :class => 'comments'),
31 :class => 'created-at' 33 :class => 'created-at'
@@ -34,6 +36,24 @@ module ContentViewerHelper @@ -34,6 +36,24 @@ module ContentViewerHelper
34 title 36 title
35 end 37 end
36 38
  39 + def show_with_right_format_date article
  40 + date_format = article.environment.date_format
  41 + use_numbers = false
  42 + year = true
  43 + left_time = false
  44 + if date_format == 'numbers_with_year'
  45 + use_numbers = true
  46 + elsif date_format == 'numbers'
  47 + use_numbers = true
  48 + year = false
  49 + elsif date_format == 'month_name'
  50 + year = false
  51 + elsif date_format == 'past_time'
  52 + left_time = true
  53 + end
  54 + content_tag('span', show_date(article.published_at, use_numbers , year, left_time), :class => 'date')
  55 + end
  56 +
37 def link_to_comments(article, args = {}) 57 def link_to_comments(article, args = {})
38 return '' unless article.accept_comments? 58 return '' unless article.accept_comments?
39 reference_to_article number_of_comments(article), article, 'comments_list' 59 reference_to_article number_of_comments(article), article, 'comments_list'
app/helpers/dates_helper.rb
@@ -2,6 +2,7 @@ require &#39;noosfero/i18n&#39; @@ -2,6 +2,7 @@ require &#39;noosfero/i18n&#39;
2 2
3 module DatesHelper 3 module DatesHelper
4 4
  5 + include ActionView::Helpers::DateHelper
5 def months 6 def months
6 I18n.t('date.month_names') 7 I18n.t('date.month_names')
7 end 8 end
@@ -15,10 +16,12 @@ module DatesHelper @@ -15,10 +16,12 @@ module DatesHelper
15 end 16 end
16 17
17 # formats a date for displaying. 18 # formats a date for displaying.
18 - def show_date(date, use_numbers = false, year=true) 19 + def show_date(date, use_numbers = false, year = true, left_time = false)
19 if date && use_numbers 20 if date && use_numbers
20 date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}') 21 date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}')
21 date_format % { :day => date.day, :month => date.month, :year => date.year } 22 date_format % { :day => date.day, :month => date.month, :year => date.year }
  23 + elsif date && left_time
  24 + date_format = time_ago_in_words(date)
22 elsif date 25 elsif date
23 date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}') 26 date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}')
24 date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year } 27 date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year }
app/helpers/events_helper.rb
1 module EventsHelper 1 module EventsHelper
2 2
  3 + include DatesHelper
3 def list_events(date, events) 4 def list_events(date, events)
4 title = _('Events for %s') % show_date_month(date) 5 title = _('Events for %s') % show_date_month(date)
5 content_tag('h2', title) + 6 content_tag('h2', title) +
app/helpers/folder_helper.rb
@@ -25,49 +25,32 @@ module FolderHelper @@ -25,49 +25,32 @@ module FolderHelper
25 articles.select {|article| article.display_to?(user)} 25 articles.select {|article| article.display_to?(user)}
26 end 26 end
27 27
28 - def display_content_in_listing(configure={})  
29 - recursive = configure[:recursive] || false  
30 - list_type = configure[:list_type] || :folder  
31 - level = configure[:level] || 0  
32 - content = FilePresenter.for configure[:content] 28 + def display_content_icon(content_item)
  29 + content = FilePresenter.for content_item
33 content_link = if content.image? 30 content_link = if content.image?
34 - link_to('&nbsp;' * (level * 4) +  
35 - image_tag(icon_for_article(content)) + short_filename(content.name), 31 + link_to(
  32 + image_tag(icon_for_article(content, :bigicon)),
36 content.url.merge(:view => true) 33 content.url.merge(:view => true)
37 ) 34 )
38 else 35 else
39 - link_to('&nbsp;' * (level * 4) +  
40 - short_filename(content.name),  
41 - content.url.merge(:view => true), :class => icon_for_article(content) 36 + link_to('',
  37 + content.url.merge(:view => true),
  38 + :class => icon_for_article(content, :bigicon)
42 ) 39 )
43 end 40 end
44 - result = content_tag(  
45 - 'tr',  
46 - content_tag('td', content_link ) +  
47 - content_tag('td', show_date(content.updated_at), :class => 'last-update'),  
48 - :class => "#{list_type}-item"  
49 - )  
50 - if recursive  
51 - result + content.children.map {|item|  
52 - display_content_in_listing :content=>item, :recursive=>recursive,  
53 - :list_type=>list_type, :level=>level+1  
54 - }.join("\n")  
55 - else  
56 - result  
57 - end  
58 end 41 end
59 42
60 - def icon_for_article(article) 43 + def icon_for_article(article, size = 'icon')
61 article = FilePresenter.for article 44 article = FilePresenter.for article
62 - icon = article.respond_to?(:icon_name) ?  
63 - article.icon_name :  
64 - article.class.icon_name(article)  
65 - if (icon =~ /\//)  
66 - icon 45 + if article.respond_to?(:sized_icon)
  46 + article.sized_icon(size)
67 else 47 else
68 - klasses = 'icon ' + [icon].flatten.map{|name| 'icon-'+name}.join(' ') 48 + icon = article.respond_to?(:icon_name) ?
  49 + article.icon_name :
  50 + article.class.icon_name(article)
  51 + klasses = "#{size} " + [icon].flatten.map{|name| "#{size}-"+name}.join(' ')
69 if article.kind_of?(UploadedFile) || article.kind_of?(FilePresenter) 52 if article.kind_of?(UploadedFile) || article.kind_of?(FilePresenter)
70 - klasses += ' icon-upload-file' 53 + klasses += " #{size}-upload-file"
71 end 54 end
72 klasses 55 klasses
73 end 56 end
app/helpers/forum_helper.rb
1 module ForumHelper 1 module ForumHelper
  2 + include ActionView::Helpers::DateHelper
2 3
3 def cms_label_for_new_children 4 def cms_label_for_new_children
4 _('New discussion topic') 5 _('New discussion topic')
@@ -42,9 +43,9 @@ module ForumHelper @@ -42,9 +43,9 @@ module ForumHelper
42 def last_topic_update(article) 43 def last_topic_update(article)
43 info = article.info_from_last_update 44 info = article.info_from_last_update
44 if info[:author_url] 45 if info[:author_url]
45 - time_ago_as_sentence(info[:date]) + ' ' + _('by') + ' ' + link_to(info[:author_name], info[:author_url]) 46 + time_ago_in_words(info[:date]) + ' ' + _('by') + ' ' + link_to(info[:author_name], info[:author_url])
46 else 47 else
47 - time_ago_as_sentence(info[:date]) + ' ' + _('by') + ' ' + info[:author_name] 48 + time_ago_in_words(info[:date]) + ' ' + _('by') + ' ' + info[:author_name]
48 end 49 end
49 end 50 end
50 51
app/models/add_friend.rb
@@ -54,7 +54,7 @@ class AddFriend &lt; Task @@ -54,7 +54,7 @@ class AddFriend &lt; Task
54 end 54 end
55 55
56 def remove_from_suggestion_list(task) 56 def remove_from_suggestion_list(task)
57 - suggestion = task.requestor.profile_suggestions.find_by_suggestion_id task.target.id 57 + suggestion = task.requestor.suggested_profiles.find_by_suggestion_id task.target.id
58 suggestion.disable if suggestion 58 suggestion.disable if suggestion
59 end 59 end
60 end 60 end
app/models/article.rb
@@ -28,7 +28,7 @@ class Article &lt; ActiveRecord::Base @@ -28,7 +28,7 @@ class Article &lt; ActiveRecord::Base
28 def initialize(*params) 28 def initialize(*params)
29 super 29 super
30 30
31 - if !params.blank? && params.first.has_key?(:profile) 31 + if !params.blank? && params.first.has_key?(:profile) && !params.first[:profile].blank?
32 profile = params.first[:profile] 32 profile = params.first[:profile]
33 self.published = false unless profile.public? 33 self.published = false unless profile.public?
34 end 34 end
@@ -96,6 +96,8 @@ class Article &lt; ActiveRecord::Base @@ -96,6 +96,8 @@ class Article &lt; ActiveRecord::Base
96 belongs_to :translation_of, :class_name => 'Article', :foreign_key => :translation_of_id 96 belongs_to :translation_of, :class_name => 'Article', :foreign_key => :translation_of_id
97 before_destroy :rotate_translations 97 before_destroy :rotate_translations
98 98
  99 + acts_as_voteable
  100 +
99 before_create do |article| 101 before_create do |article|
100 article.published_at ||= Time.now 102 article.published_at ||= Time.now
101 if article.reference_article && !article.parent 103 if article.reference_article && !article.parent
app/models/blog.rb
@@ -76,9 +76,12 @@ class Blog &lt; Folder @@ -76,9 +76,12 @@ class Blog &lt; Folder
76 end 76 end
77 77
78 settings_items :visualization_format, :type => :string, :default => 'full' 78 settings_items :visualization_format, :type => :string, :default => 'full'
79 - validates_inclusion_of :visualization_format, :in => [ 'full', 'short', 'short+pic' ], :if => :visualization_format 79 + validates_inclusion_of :visualization_format,
  80 + :in => [ 'full', 'short', 'short+pic', 'compact'],
  81 + :if => :visualization_format
80 82
81 - settings_items :display_posts_in_current_language, :type => :boolean, :default => false 83 + settings_items :display_posts_in_current_language,
  84 + :type => :boolean, :default => false
82 85
83 alias :display_posts_in_current_language? :display_posts_in_current_language 86 alias :display_posts_in_current_language? :display_posts_in_current_language
84 87
app/models/comment.rb
@@ -39,6 +39,8 @@ class Comment &lt; ActiveRecord::Base @@ -39,6 +39,8 @@ class Comment &lt; ActiveRecord::Base
39 39
40 xss_terminate :only => [ :body, :title, :name ], :on => 'validation' 40 xss_terminate :only => [ :body, :title, :name ], :on => 'validation'
41 41
  42 + acts_as_voteable
  43 +
42 def comment_root 44 def comment_root
43 (reply_of && reply_of.comment_root) || self 45 (reply_of && reply_of.comment_root) || self
44 end 46 end
app/models/environment.rb
@@ -3,7 +3,17 @@ @@ -3,7 +3,17 @@
3 # domains. 3 # domains.
4 class Environment < ActiveRecord::Base 4 class Environment < ActiveRecord::Base
5 5
6 - attr_accessible :name, :is_default, :signup_welcome_text_subject, :signup_welcome_text_body, :terms_of_use, :message_for_disabled_enterprise, :news_amount_by_folder, :default_language, :languages, :description, :organization_approval_method, :enabled_plugins, :enabled_features, :redirection_after_login, :redirection_after_signup, :contact_email, :theme, :reports_lower_bound, :noreply_email, :signup_welcome_screen_body, :members_whitelist_enabled, :members_whitelist, :highlighted_news_amount, :portal_news_amount 6 + attr_accessible :name, :is_default, :signup_welcome_text_subject,
  7 + :signup_welcome_text_body, :terms_of_use,
  8 + :message_for_disabled_enterprise, :news_amount_by_folder,
  9 + :default_language, :languages, :description,
  10 + :organization_approval_method, :enabled_plugins,
  11 + :enabled_features, :redirection_after_login,
  12 + :redirection_after_signup, :contact_email, :theme,
  13 + :reports_lower_bound, :noreply_email,
  14 + :signup_welcome_screen_body, :members_whitelist_enabled,
  15 + :members_whitelist, :highlighted_news_amount,
  16 + :portal_news_amount, :date_format
7 17
8 has_many :users 18 has_many :users
9 19
@@ -14,6 +24,12 @@ class Environment &lt; ActiveRecord::Base @@ -14,6 +24,12 @@ class Environment &lt; ActiveRecord::Base
14 24
15 IDENTIFY_SCRIPTS = /(php[0-9s]?|[sp]htm[l]?|pl|py|cgi|rb)/ 25 IDENTIFY_SCRIPTS = /(php[0-9s]?|[sp]htm[l]?|pl|py|cgi|rb)/
16 26
  27 + validates_inclusion_of :date_format,
  28 + :in => [ 'numbers_with_year', 'numbers',
  29 + 'month_name_with_year', 'month_name',
  30 + 'past_time'],
  31 + :if => :date_format
  32 +
17 def self.verify_filename(filename) 33 def self.verify_filename(filename)
18 filename += '.txt' if File.extname(filename) =~ IDENTIFY_SCRIPTS 34 filename += '.txt' if File.extname(filename) =~ IDENTIFY_SCRIPTS
19 filename 35 filename
@@ -75,7 +91,8 @@ class Environment &lt; ActiveRecord::Base @@ -75,7 +91,8 @@ class Environment &lt; ActiveRecord::Base
75 'edit_profile_design', 91 'edit_profile_design',
76 'manage_products', 92 'manage_products',
77 'manage_friends', 93 'manage_friends',
78 - 'perform_task' 94 + 'perform_task',
  95 + 'view_tasks'
79 ] 96 ]
80 ) 97 )
81 end 98 end
app/models/person.rb
@@ -92,9 +92,9 @@ roles] } @@ -92,9 +92,9 @@ roles] }
92 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' 92 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
93 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' 93 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions'
94 94
95 - has_many :profile_suggestions, :foreign_key => :person_id, :order => 'score DESC', :dependent => :destroy  
96 - has_many :suggested_people, :through => :profile_suggestions, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Person', true]  
97 - has_many :suggested_communities, :through => :profile_suggestions, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Community', true] 95 + has_many :suggested_profiles, :class_name => 'ProfileSuggestion', :foreign_key => :person_id, :order => 'score DESC', :dependent => :destroy
  96 + has_many :suggested_people, :through => :suggested_profiles, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Person', true]
  97 + has_many :suggested_communities, :through => :suggested_profiles, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Community', true]
98 98
99 scope :more_popular, :order => 'friends_count DESC' 99 scope :more_popular, :order => 'friends_count DESC'
100 100
@@ -111,6 +111,8 @@ roles] } @@ -111,6 +111,8 @@ roles] }
111 111
112 belongs_to :user, :dependent => :delete 112 belongs_to :user, :dependent => :delete
113 113
  114 + acts_as_voter
  115 +
114 def can_change_homepage? 116 def can_change_homepage?
115 !environment.enabled?('cant_change_homepage') || is_admin? 117 !environment.enabled?('cant_change_homepage') || is_admin?
116 end 118 end
@@ -535,7 +537,7 @@ roles] } @@ -535,7 +537,7 @@ roles] }
535 end 537 end
536 538
537 def remove_suggestion(profile) 539 def remove_suggestion(profile)
538 - suggestion = profile_suggestions.find_by_suggestion_id profile.id 540 + suggestion = suggested_profiles.find_by_suggestion_id profile.id
539 suggestion.disable if suggestion 541 suggestion.disable if suggestion
540 end 542 end
541 543
app/models/profile.rb
@@ -71,6 +71,7 @@ class Profile &lt; ActiveRecord::Base @@ -71,6 +71,7 @@ class Profile &lt; ActiveRecord::Base
71 'manage_friends' => N_('Manage friends'), 71 'manage_friends' => N_('Manage friends'),
72 'validate_enterprise' => N_('Validate enterprise'), 72 'validate_enterprise' => N_('Validate enterprise'),
73 'perform_task' => N_('Perform task'), 73 'perform_task' => N_('Perform task'),
  74 + 'view_tasks' => N_('View tasks'),
74 'moderate_comments' => N_('Moderate comments'), 75 'moderate_comments' => N_('Moderate comments'),
75 'edit_appearance' => N_('Edit appearance'), 76 'edit_appearance' => N_('Edit appearance'),
76 'view_private_content' => N_('View private content'), 77 'view_private_content' => N_('View private content'),
@@ -969,19 +970,11 @@ private :generate_url, :url_options @@ -969,19 +970,11 @@ private :generate_url, :url_options
969 self.save 970 self.save
970 end 971 end
971 972
972 - def disabled?  
973 - !visible  
974 - end  
975 -  
976 def enable 973 def enable
977 self.visible = true 974 self.visible = true
978 self.save 975 self.save
979 end 976 end
980 977
981 - def enabled?  
982 - visible  
983 - end  
984 -  
985 def control_panel_settings_button 978 def control_panel_settings_button
986 {:title => _('Edit Profile'), :icon => 'edit-profile'} 979 {:title => _('Edit Profile'), :icon => 'edit-profile'}
987 end 980 end
@@ -1041,7 +1034,7 @@ private :generate_url, :url_options @@ -1041,7 +1034,7 @@ private :generate_url, :url_options
1041 end 1034 end
1042 1035
1043 def remove_from_suggestion_list(person) 1036 def remove_from_suggestion_list(person)
1044 - suggestion = person.profile_suggestions.find_by_suggestion_id self.id 1037 + suggestion = person.suggested_profiles.find_by_suggestion_id self.id
1045 suggestion.disable if suggestion 1038 suggestion.disable if suggestion
1046 end 1039 end
1047 1040
app/models/profile_suggestion.rb
@@ -113,14 +113,14 @@ class ProfileSuggestion &lt; ActiveRecord::Base @@ -113,14 +113,14 @@ class ProfileSuggestion &lt; ActiveRecord::Base
113 suggested_profiles = all_suggestions(person) 113 suggested_profiles = all_suggestions(person)
114 return if suggested_profiles.nil? 114 return if suggested_profiles.nil?
115 115
116 - already_suggested_profiles = person.profile_suggestions.map(&:suggestion_id).join(',') 116 + already_suggested_profiles = person.suggested_profiles.map(&:suggestion_id).join(',')
117 suggested_profiles = suggested_profiles.where("profiles.id NOT IN (#{already_suggested_profiles})") if already_suggested_profiles.present? 117 suggested_profiles = suggested_profiles.where("profiles.id NOT IN (#{already_suggested_profiles})") if already_suggested_profiles.present?
118 #TODO suggested_profiles = suggested_profiles.order('score DESC') 118 #TODO suggested_profiles = suggested_profiles.order('score DESC')
119 suggested_profiles = suggested_profiles.limit(N_SUGGESTIONS) 119 suggested_profiles = suggested_profiles.limit(N_SUGGESTIONS)
120 return if suggested_profiles.blank? 120 return if suggested_profiles.blank?
121 121
122 suggested_profiles.each do |suggested_profile| 122 suggested_profiles.each do |suggested_profile|
123 - suggestion = person.profile_suggestions.find_or_initialize_by_suggestion_id(suggested_profile.id) 123 + suggestion = person.suggested_profiles.find_or_initialize_by_suggestion_id(suggested_profile.id)
124 RULES.each do |rule, options| 124 RULES.each do |rule, options|
125 begin 125 begin
126 value = suggested_profile.send("#{rule}_count").to_i 126 value = suggested_profile.send("#{rule}_count").to_i
@@ -273,7 +273,7 @@ class ProfileSuggestion &lt; ActiveRecord::Base @@ -273,7 +273,7 @@ class ProfileSuggestion &lt; ActiveRecord::Base
273 end 273 end
274 274
275 def self.generate_profile_suggestions(person, force = false) 275 def self.generate_profile_suggestions(person, force = false)
276 - return if person.profile_suggestions.enabled.count >= MIN_LIMIT && !force 276 + return if person.suggested_profiles.enabled.count >= MIN_LIMIT && !force
277 Delayed::Job.enqueue ProfileSuggestionsJob.new(person.id) unless ProfileSuggestionsJob.exists?(person.id) 277 Delayed::Job.enqueue ProfileSuggestionsJob.new(person.id) unless ProfileSuggestionsJob.exists?(person.id)
278 end 278 end
279 279
app/models/task.rb
@@ -34,6 +34,7 @@ class Task &lt; ActiveRecord::Base @@ -34,6 +34,7 @@ class Task &lt; ActiveRecord::Base
34 belongs_to :requestor, :class_name => 'Profile', :foreign_key => :requestor_id 34 belongs_to :requestor, :class_name => 'Profile', :foreign_key => :requestor_id
35 belongs_to :target, :foreign_key => :target_id, :polymorphic => true 35 belongs_to :target, :foreign_key => :target_id, :polymorphic => true
36 belongs_to :responsible, :class_name => 'Person', :foreign_key => :responsible_id 36 belongs_to :responsible, :class_name => 'Person', :foreign_key => :responsible_id
  37 + belongs_to :closed_by, :class_name => 'Person', :foreign_key => :closed_by_id
37 38
38 validates_uniqueness_of :code, :on => :create 39 validates_uniqueness_of :code, :on => :create
39 validates_presence_of :code 40 validates_presence_of :code
@@ -77,11 +78,9 @@ class Task &lt; ActiveRecord::Base @@ -77,11 +78,9 @@ class Task &lt; ActiveRecord::Base
77 # this method finished the task. It calls #perform, which must be overriden 78 # this method finished the task. It calls #perform, which must be overriden
78 # by subclasses. At the end a message (as returned by #finish_message) is 79 # by subclasses. At the end a message (as returned by #finish_message) is
79 # sent to the requestor with #notify_requestor. 80 # sent to the requestor with #notify_requestor.
80 - def finish 81 + def finish(closed_by=nil)
81 transaction do 82 transaction do
82 - self.status = Task::Status::FINISHED  
83 - self.end_date = Time.now  
84 - self.save! 83 + close(Task::Status::FINISHED, closed_by)
85 self.perform 84 self.perform
86 begin 85 begin
87 send_notification(:finished) 86 send_notification(:finished)
@@ -106,11 +105,9 @@ class Task &lt; ActiveRecord::Base @@ -106,11 +105,9 @@ class Task &lt; ActiveRecord::Base
106 105
107 # this method cancels the task. At the end a message (as returned by 106 # this method cancels the task. At the end a message (as returned by
108 # #cancel_message) is sent to the requestor with #notify_requestor. 107 # #cancel_message) is sent to the requestor with #notify_requestor.
109 - def cancel 108 + def cancel(closed_by=nil)
110 transaction do 109 transaction do
111 - self.status = Task::Status::CANCELLED  
112 - self.end_date = Time.now  
113 - self.save! 110 + close(Task::Status::CANCELLED, closed_by)
114 begin 111 begin
115 send_notification(:cancelled) 112 send_notification(:cancelled)
116 rescue NotImplementedError => ex 113 rescue NotImplementedError => ex
@@ -119,6 +116,13 @@ class Task &lt; ActiveRecord::Base @@ -119,6 +116,13 @@ class Task &lt; ActiveRecord::Base
119 end 116 end
120 end 117 end
121 118
  119 + def close(status, closed_by)
  120 + self.status = status
  121 + self.end_date = Time.now
  122 + self.closed_by = closed_by
  123 + self.save!
  124 + end
  125 +
122 # Here are the tasks customizable options. 126 # Here are the tasks customizable options.
123 127
124 def title 128 def title
app/models/uploaded_file.rb
@@ -65,7 +65,7 @@ class UploadedFile &lt; Article @@ -65,7 +65,7 @@ class UploadedFile &lt; Article
65 # :min_size => 2.megabytes 65 # :min_size => 2.megabytes
66 # :max_size => 5.megabytes 66 # :max_size => 5.megabytes
67 has_attachment :storage => :file_system, 67 has_attachment :storage => :file_system,
68 - :thumbnails => { :icon => [24,24], :thumb => '130x130>', :slideshow => '320x240>', :display => '640X480>' }, 68 + :thumbnails => { :icon => [24,24], :bigicon => [50,50], :thumb => '130x130>', :slideshow => '320x240>', :display => '640X480>' },
69 :thumbnail_class => Thumbnail, 69 :thumbnail_class => Thumbnail,
70 :max_size => self.max_size 70 :max_size => self.max_size
71 71
app/presenters/image.rb
@@ -4,6 +4,10 @@ class FilePresenter::Image &lt; FilePresenter @@ -4,6 +4,10 @@ class FilePresenter::Image &lt; FilePresenter
4 f.image? ? 10 : nil 4 f.image? ? 10 : nil
5 end 5 end
6 6
  7 + def sized_icon(size)
  8 + public_filename size
  9 + end
  10 +
7 def icon_name 11 def icon_name
8 public_filename :icon 12 public_filename :icon
9 end 13 end
app/views/admin_panel/_site_info.html.erb
@@ -3,6 +3,21 @@ @@ -3,6 +3,21 @@
3 <%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %> 3 <%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %>
4 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %> 4 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %>
5 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %> 5 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %>
  6 +
  7 +<%= labelled_form_field(
  8 + _("Article's date format"),
  9 + select(:environment, :date_format,
  10 + options_for_select([
  11 + [ _('mm/dd/yyyy'), 'numbers_with_year'],
  12 + [ _('mm/dd'), 'numbers'],
  13 + [ _('Month dd, yyyy'), 'month_name_with_year'],
  14 + [ _('Month dd'), 'month_name'],
  15 + [ _('X minutes/hours/days/months/years ago'), 'past_time']
  16 + ], environment.date_format
  17 + )
  18 + )
  19 +) %>
  20 +
6 <%= required f.text_field(:reports_lower_bound, :size => 3) %> 21 <%= required f.text_field(:reports_lower_bound, :size => 3) %>
7 <%= labelled_form_field(_('Default language'), select(:environment, :default_language, environment.locales.invert, { :selected => environment.default_locale, :include_blank => true })) %> 22 <%= labelled_form_field(_('Default language'), select(:environment, :default_language, environment.locales.invert, { :selected => environment.default_locale, :include_blank => true })) %>
8 <%= label_tag :languages, _('Available languages') %> 23 <%= label_tag :languages, _('Available languages') %>
app/views/blocks/profile_info_actions/_common.html.erb
1 <li><%= report_abuse(profile, :button) %></li> 1 <li><%= report_abuse(profile, :button) %></li>
2 -<%= render_environment_features(:profile_actions) %></li> 2 +<%= render_environment_features(:profile_actions) %>
app/views/box_organizer/edit.html.erb
@@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@
25 </div> 25 </div>
26 <div class="move-modes"> 26 <div class="move-modes">
27 <%= labelled_form_field _('Move options:'), select_tag('block[move_modes]', options_from_collection_for_select(@block.move_block_options, :first, :last, @block.move_modes)) %> 27 <%= labelled_form_field _('Move options:'), select_tag('block[move_modes]', options_from_collection_for_select(@block.move_block_options, :first, :last, @block.move_modes)) %>
  28 + </div>
28 <% end %> 29 <% end %>
29 30
30 <% if @block.owner.kind_of?(Profile) && @block.owner.is_template? %> 31 <% if @block.owner.kind_of?(Profile) && @block.owner.is_template? %>
app/views/cms/_blog.html.erb
@@ -67,7 +67,8 @@ @@ -67,7 +67,8 @@
67 <%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ 67 <%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [
68 [ _('Full post'), 'full'], 68 [ _('Full post'), 'full'],
69 [ _('First paragraph'), 'short'], 69 [ _('First paragraph'), 'short'],
70 - [ _('First paragraph, with post picture'), 'short+pic'] 70 + [ _('First paragraph, with post picture'), 'short+pic'],
  71 + [ _("Title, Image, Lead"), 'compact']
71 ])) %> 72 ])) %>
72 73
73 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %> 74 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %>
app/views/content_viewer/_article_toolbar.html.erb
@@ -62,7 +62,7 @@ @@ -62,7 +62,7 @@
62 <% if @page.blog? and !@page.image.nil? %> 62 <% if @page.blog? and !@page.image.nil? %>
63 <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div> 63 <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div>
64 <% end %> 64 <% end %>
65 - <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> 65 + <%= link_to(image_tag('/images/icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
66 <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %> 66 <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
67 <%= article_title(@page, :no_link => true) %> 67 <%= article_title(@page, :no_link => true) %>
68 <%= article_translations(@page) %> 68 <%= article_translations(@page) %>
app/views/content_viewer/_display_compact_format.html.erb 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +<% if article.image %>
  2 + <% className = "article-compact-abstract-with-image" %>
  3 + <% if article.image.thumbnails_processed? %>
  4 + <% image_file = article.image.public_filename(:big) %>
  5 + <% else %>
  6 + <% image_file = "/images/icons-app/image-loading-thumb.png" %>
  7 + <% end %>
  8 +<% else %>
  9 + <% className = "article-compact-abstract" %>
  10 +<% end %>
  11 +
  12 +<div>
  13 + <% if article.image %>
  14 + <div class = "article-compact-image">
  15 + <%= image_tag(image_file) %>
  16 + </div>
  17 + <% end %>
  18 + <div class = <%= className %> >
  19 + <%= article.abstract.truncate(400) %>
  20 + </div>
  21 +</div>
app/views/content_viewer/blog_page.html.erb
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 </div> 8 </div>
9 </div> 9 </div>
10 <hr class="pre-posts"/> 10 <hr class="pre-posts"/>
11 -<div class="blog-posts"> 11 +<div class="blog-posts page-<%= @npage %>">
12 <% paginate = true %> 12 <% paginate = true %>
13 <%= 13 <%=
14 posts = @posts 14 posts = @posts
app/views/content_viewer/folder.html.erb
1 <% unless folder.body.blank? %> 1 <% unless folder.body.blank? %>
2 - <div> 2 + <div class="folder-description">
3 <%= folder.body %> 3 <%= folder.body %>
4 </div> 4 </div>
5 - <hr/>  
6 <% end %> 5 <% end %>
7 6
8 <% if folder.children.empty? %> 7 <% if folder.children.empty? %>
app/views/person_notifier/mailer/_comment.html.erb
@@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
19 <span style="font-size: 12px;"><%= comment.title %></span><br/> 19 <span style="font-size: 12px;"><%= comment.title %></span><br/>
20 <% end %> 20 <% end %>
21 <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/> 21 <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/>
22 - <span style="font-size: 8px; color: #929292"><%= time_ago_as_sentence(comment.created_at) %></span> 22 + <span style="font-size: 8px; color: #929292"><%= time_ago_in_words(comment.created_at) %></span>
23 <br style="clear: both;" /> 23 <br style="clear: both;" />
24 24
25 <% unless comment.replies.blank? %> 25 <% unless comment.replies.blank? %>
app/views/person_notifier/mailer/_create_article.html.erb
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <p> 6 <p>
7 <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span> 7 <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span>
8 <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span> 8 <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span>
9 - <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> 9 + <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_in_words(activity.created_at) %></span>
10 </p> 10 </p>
11 <p> 11 <p>
12 <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span> 12 <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span>
app/views/person_notifier/mailer/_default_activity.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <td> 5 <td>
6 <p> 6 <p>
7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> 7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span>
8 - <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span> 8 + <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_in_words(activity.created_at) %></span>
9 </p> 9 </p>
10 </td> 10 </td>
11 </tr> 11 </tr>
app/views/person_notifier/mailer/_task.html.erb
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <span style="font-size: 14px"> 12 <span style="font-size: 14px">
13 <%= task_information(task) %> 13 <%= task_information(task) %>
14 </span> 14 </span>
15 - <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_as_sentence(task.created_at) %></span> 15 + <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_in_words(task.created_at) %></span>
16 </div> 16 </div>
17 </td> 17 </td>
18 </tr> 18 </tr>
app/views/person_notifier/mailer/_upload_image.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <td> 5 <td>
6 <p> 6 <p>
7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> 7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span>
8 - <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> 8 + <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_in_words(activity.created_at) %></span>
9 </p> 9 </p>
10 </td> 10 </td>
11 </tr> 11 </tr>
app/views/profile/_comment.html.erb
@@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
40 <%= txt2html comment.body %> 40 <%= txt2html comment.body %>
41 </div> 41 </div>
42 <div class="profile-activity-time"> 42 <div class="profile-activity-time">
43 - <%= time_ago_as_sentence(comment.created_at) %> 43 + <%= time_ago_in_words(comment.created_at) %>
44 </div> 44 </div>
45 </div> 45 </div>
46 46
app/views/profile/_create_article.html.erb
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') unless activity.params['lead'].blank? %> <small><%= link_to(_('See more'), activity.params['url']) unless activity.get_lead.blank? %></small> 12 <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') unless activity.params['lead'].blank? %> <small><%= link_to(_('See more'), activity.params['url']) unless activity.get_lead.blank? %></small>
13 </div> 13 </div>
14 <%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %> 14 <%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %>
15 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 15 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
16 <div class='profile-wall-actions'> 16 <div class='profile-wall-actions'>
17 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %> 17 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %>
18 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :only_hide => true, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 18 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :only_hide => true, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
app/views/profile/_default_activity.html.erb
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 </div> 3 </div>
4 <div class='profile-activity-description'> 4 <div class='profile-activity-description'>
5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p> 5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
6 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 6 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
7 <div class='profile-wall-actions'> 7 <div class='profile-wall-actions'>
8 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %> 8 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %>
9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
app/views/profile/_leave_scrap.html.erb
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 </div> 3 </div>
4 <div class='profile-activity-description'> 4 <div class='profile-activity-description'>
5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p> 5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
6 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 6 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
7 <div class='profile-wall-actions'> 7 <div class='profile-wall-actions'>
8 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 8 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
9 </div> 9 </div>
app/views/profile/_profile_scrap.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <div class='profile-activity-description'> 5 <div class='profile-activity-description'>
6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p> 6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
7 <p class='profile-activity-text'><%= txt2html scrap.content %></p> 7 <p class='profile-activity-text'><%= txt2html scrap.content %></p>
8 - <p class='profile-activity-time'><%= time_ago_as_sentence(scrap.created_at) %></p> 8 + <p class='profile-activity-time'><%= time_ago_in_words(scrap.created_at) %></p>
9 <div class='profile-wall-actions'> 9 <div class='profile-wall-actions'>
10 <% if logged_in? && current_person.follows?(scrap.sender) %> 10 <% if logged_in? && current_person.follows?(scrap.sender) %>
11 <span class='profile-activity-send-reply'> 11 <span class='profile-activity-send-reply'>
@@ -22,5 +22,5 @@ @@ -22,5 +22,5 @@
22 <% end %> 22 <% end %>
23 </ul> 23 </ul>
24 <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %> 24 <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %>
25 - <hr /> 25 + <hr />
26 </li> 26 </li>
app/views/profile/_profile_scraps.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <div class='profile-activity-description'> 5 <div class='profile-activity-description'>
6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p> 6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
7 <p class='profile-activity-text'><%= txt2html scrap.content %></p> 7 <p class='profile-activity-text'><%= txt2html scrap.content %></p>
8 - <p class='profile-activity-time'><%= time_ago_as_sentence(scrap.created_at) %></p> 8 + <p class='profile-activity-time'><%= time_ago_in_words(scrap.created_at) %></p>
9 <div class='profile-wall-actions'> 9 <div class='profile-wall-actions'>
10 <% if logged_in? && current_person.follows?(scrap.sender) %> 10 <% if logged_in? && current_person.follows?(scrap.sender) %>
11 <span class='profile-activity-send-reply'> 11 <span class='profile-activity-send-reply'>
app/views/profile/_upload_image.html.erb
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 </div> 4 </div>
5 <div class='profile-activity-description'> 5 <div class='profile-activity-description'>
6 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p> 6 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
7 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 7 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
8 <div class='profile-wall-actions'> 8 <div class='profile-wall-actions'>
9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
10 </div> 10 </div>
app/views/profile/content_tagged.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <h1><%= _('Content tagged with "%s"') % escaped_tag %></h1> 5 <h1><%= _('Content tagged with "%s"') % escaped_tag %></h1>
6 6
7 <p> 7 <p>
8 -<%= link_to image_tag('icons-mime/rss-feed.png', :alt => _('Feed for this tag'), :title => _('Feed for this tag')), tag_feed_path, :class => 'blog-feed-link'%> 8 +<%= link_to image_tag('/images/icons-mime/rss-feed.png', :alt => _('Feed for this tag'), :title => _('Feed for this tag')), tag_feed_path, :class => 'blog-feed-link'%>
9 </p> 9 </p>
10 10
11 <% cache_timeout(@tag_cache_key, 4.hour) do %> 11 <% cache_timeout(@tag_cache_key, 4.hour) do %>
app/views/shared/_content_item.html.erb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +<div id="list-item">
  2 + <div class="item-info">
  3 + <div class="item-icon" >
  4 + <%= display_content_icon(content) %>
  5 + </div>
  6 + <span class="item-description">
  7 + <%= link_to(short_filename_upper_ext(content.name), content.url) %>
  8 + </span>
  9 + <span class="item-date"><%= _("Published at: #{show_date(content.updated_at)}") %></span>
  10 + </div>
  11 +</div>
0 \ No newline at end of file 12 \ No newline at end of file
app/views/shared/_lead_and_body.html.erb
@@ -19,17 +19,27 @@ @@ -19,17 +19,27 @@
19 19
20 <div class='article-lead' id="article-lead-<%=lead_id.to_s%>"> 20 <div class='article-lead' id="article-lead-<%=lead_id.to_s%>">
21 21
  22 + <% abstract_options = {:style => 'width: 100%; height: 200px;', :class => editor_type} %>
22 <% if f %> 23 <% if f %>
23 - <%= labelled_form_field(_(abstract_label), f.text_area(abstract_method, :style => 'width: 100%; height: 200px;', :class => editor_type)) %> 24 + <%= labelled_form_field(_(abstract_label), f.text_area(abstract_method, abstract_options)) %>
24 <% else %> 25 <% else %>
25 - <%= labelled_form_field(_(abstract_label), text_area(object, abstract_method, :style => 'width: 100%; height: 200px;', :class => editor_type)) %> 26 + <% if @article.kind_of?(Article) %>
  27 + <%= labelled_form_field(_(abstract_label), text_area_tag("article[abstract]", @escaped_abstract, abstract_options)) %>
  28 + <% else %>
  29 + <%= labelled_form_field(_(abstract_label), text_area(object, abstract_method, abstract_options)) %>
  30 + <% end %>
26 <% end %> 31 <% end %>
27 </div> 32 </div>
28 <div style="margin-top: 10px;"> 33 <div style="margin-top: 10px;">
  34 + <% body_options = {:style => 'width: 100%; height: 400px;', :class => editor_type} %>
29 <% if f %> 35 <% if f %>
30 - <%= labelled_form_field(_(body_label), f.text_area(body_method, :style => 'width: 100%; height: 400px;', :class => editor_type)) %> 36 + <%= labelled_form_field(_(body_label), f.text_area(body_method, body_options)) %>
31 <% else %> 37 <% else %>
32 - <%= labelled_form_field(_(body_label), text_area(object, body_method, :style => 'width: 100%; height: 400px;', :class => editor_type)) %> 38 + <% if @article.kind_of?(Article) %>
  39 + <%= labelled_form_field(_(body_label), text_area_tag("article[body]", @escaped_body, body_options)) %>
  40 + <% else %>
  41 + <%= labelled_form_field(_(body_label), text_area(object, body_method, body_options)) %>
  42 + <% end %>
33 <% end %> 43 <% end %>
34 </div> 44 </div>
35 45
app/views/shared/content_list.html.erb
1 -<table class="<%= list_type %>-content">  
2 - <tr>  
3 - <th><%= _('Title') %></th>  
4 - <th><%= _('Last update') %></th>  
5 - </tr> 1 +<ul class="<%= list_type %>-content">
6 <% contents.each do |content| %> 2 <% contents.each do |content| %>
7 - <% if content.display_to?(user) %>  
8 - <%= display_content_in_listing :content=>content, :list_type=>list_type, :recursive=>recursive %>  
9 - <% end %> 3 + <li class="<%= list_type %>-item">
  4 + <% if content.display_to?(user) %>
  5 + <%= render :partial => 'shared/content_item', :locals => { :content => content } %>
  6 + <% end %>
  7 + </li>
10 <% end %> 8 <% end %>
11 -</table> 9 +</ul>
12 10
13 <p><%= pagination_links contents, :param_name => 'npage', :page_links => true %></p> 11 <p><%= pagination_links contents, :param_name => 'npage', :page_links => true %></p>
app/views/tasks/_abuse_complaint_accept_details.html.erb
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <% task.abuse_reports.each do |abuse_report| %> 2 <% task.abuse_reports.each do |abuse_report| %>
3 <div> 3 <div>
4 <strong style="word-wrap: break-word; display: block; padding-right: 40px">"<%= abuse_report.reason %>"</strong> <br /> 4 <strong style="word-wrap: break-word; display: block; padding-right: 40px">"<%= abuse_report.reason %>"</strong> <br />
5 - <i><%= _('Reported by %{reporter} %{time}.') % {:reporter => abuse_report.reporter.name, :time => time_ago_as_sentence(abuse_report.created_at) }%></i> <br /> 5 + <i><%= _('Reported by %{reporter} %{time}.') % {:reporter => abuse_report.reporter.name, :time => time_ago_in_words(abuse_report.created_at) }%></i> <br />
6 <% if !abuse_report.content.blank? %> 6 <% if !abuse_report.content.blank? %>
7 <button class="display-abuse-report-details" data-report="<%=abuse_report.id%>"><%=_('View details')%></button> 7 <button class="display-abuse-report-details" data-report="<%=abuse_report.id%>"><%=_('View details')%></button>
8 <div style='display: none' id=<%= 'abuse-report-details-'+abuse_report.id.to_s %> class="abuse-report-details"> 8 <div style='display: none' id=<%= 'abuse-report-details-'+abuse_report.id.to_s %> class="abuse-report-details">
app/views/tasks/_task.html.erb
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 2
3 <%= render :partial => 'task_icon', :locals => {:task => task} %> 3 <%= render :partial => 'task_icon', :locals => {:task => task} %>
4 4
5 - <% if profile.organization? && @responsible_candidates.present? %> 5 + <% if !@view_only && profile.organization? && @responsible_candidates.present? %>
6 <div class="task_responsible"> 6 <div class="task_responsible">
7 <span class="label"><%= _('Assign to:') %></span> 7 <span class="label"><%= _('Assign to:') %></span>
8 <span> 8 <span>
@@ -12,8 +12,16 @@ @@ -12,8 +12,16 @@
12 </div> 12 </div>
13 <% end %> 13 <% end %>
14 14
  15 + <% if @view_only && task.responsible.present? %>
  16 + <div class="task_responsible">
  17 + <span class="label"><%= _('Assigned to:') %></span>
  18 + <span class="value"><%= task.responsible.name %></span>
  19 + </div>
  20 + <% end %>
  21 +
15 <div class="task_decisions"> 22 <div class="task_decisions">
16 - <%= 23 + <% unless @view_only %>
  24 + <%=
17 labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.default_decision == 'accept', 25 labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.default_decision == 'accept',
18 :id => "decision-finish-#{task.id}", 26 :id => "decision-finish-#{task.id}",
19 :class => 'task_accept_radio', 27 :class => 'task_accept_radio',
@@ -29,7 +37,8 @@ @@ -29,7 +37,8 @@
29 :class => 'task_skip_radio', 37 :class => 'task_skip_radio',
30 :disabled => task.skip_disabled?, 38 :disabled => task.skip_disabled?,
31 :task_id => "#{task.id}") 39 :task_id => "#{task.id}")
32 - %> 40 + %>
  41 + <% end %>
33 </div><!-- class="task_decisions" --> 42 </div><!-- class="task_decisions" -->
34 43
35 <div class="task_date"><%= show_time(task.created_at) %></div> 44 <div class="task_date"><%= show_time(task.created_at) %></div>
app/views/tasks/index.html.erb
@@ -46,36 +46,41 @@ @@ -46,36 +46,41 @@
46 </p> 46 </p>
47 <% else %> 47 <% else %>
48 <%= form_tag :action => 'close' do%> 48 <%= form_tag :action => 'close' do%>
49 - <% button_bar do %> 49 + <% button_bar(:class => 'task-actions') do %>
50 <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %> 50 <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
51 <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %> 51 <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>
52 <%= submit_button :save, _("Apply!") %> 52 <%= submit_button :save, _("Apply!") %>
53 <%= button(:edit, _('View processed tasks'), :action => 'processed') %> 53 <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
54 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> 54 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
55 - <% end %> 55 + <% end unless @view_only %>
56 56
57 <ul class='task-list'> 57 <ul class='task-list'>
58 - <p>  
59 - <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>  
60 - </p> 58 + <% unless @view_only %>
  59 + <p>
  60 + <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
  61 + </p>
  62 + <% end %>
61 63
62 <div class="task_boxes"> 64 <div class="task_boxes">
63 <%= render :partial => 'task', :collection => @tasks %> 65 <%= render :partial => 'task', :collection => @tasks %>
64 </div> 66 </div>
65 - <p>  
66 - <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>  
67 - </p> 67 +
  68 + <% unless @view_only %>
  69 + <p>
  70 + <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>
  71 + </p>
  72 + <% end %>
68 </ul> 73 </ul>
69 74
70 <%= pagination_links(@tasks)%> 75 <%= pagination_links(@tasks)%>
71 76
72 - <% button_bar do %> 77 + <% button_bar(:class => 'task-actions') do %>
73 <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %> 78 <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
74 <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %> 79 <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>
75 <%= submit_button :save, _("Apply!") %> 80 <%= submit_button :save, _("Apply!") %>
76 <%= button(:edit, _('View processed tasks'), :action => 'processed') %> 81 <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
77 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> 82 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
78 - <% end %> 83 + <% end unless @view_only %>
79 <% end %> 84 <% end %>
80 <% end %> 85 <% end %>
81 </p> 86 </p>
config/initializers/delayed_job_config.rb
@@ -23,3 +23,13 @@ end @@ -23,3 +23,13 @@ end
23 # end 23 # end
24 # alias_method_chain :handle_failed_job, :loggin 24 # alias_method_chain :handle_failed_job, :loggin
25 #end 25 #end
  26 +
  27 +# Chain delayed job's handle_failed_job method to do exception notification
  28 +Delayed::Worker.class_eval do
  29 + def handle_failed_job_with_notification job, error
  30 + handle_failed_job_without_notification job, error
  31 + ExceptionNotifier.notify_exception error, exception_recipients: NOOSFERO_CONF['exception_recipients'],
  32 + data: {job: job, handler: job.handler} rescue nil
  33 + end
  34 + alias_method_chain :handle_failed_job, :notification
  35 +end
config/initializers/noosfero_extensions.rb
1 require 'noosfero/role_assignment_ext' 1 require 'noosfero/role_assignment_ext'
2 require 'noosfero/action_tracker_ext' 2 require 'noosfero/action_tracker_ext'
  3 +require 'noosfero/vote_ext'
db/migrate/20150423203352_fix_tags_case_differences.rb 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +class FixTagsCaseDifferences < ActiveRecord::Migration
  2 + def up
  3 + tags = ActsAsTaggableOn::Tag.joins('LEFT JOIN tags as b on LOWER(tags.name) = b.name').where('b.id is null')
  4 + tags.find_each do |tag|
  5 + unless ActsAsTaggableOn::Tag.exists?(:name => tag.name.mb_chars.downcase)
  6 + ActsAsTaggableOn::Tag.create(:name => tag.name.mb_chars.downcase)
  7 + end
  8 + end
  9 +
  10 + execute("UPDATE taggings SET tag_id = new.id FROM taggings AS t INNER JOIN tags AS old ON t.tag_id = old.id INNER JOIN tags AS new ON LOWER(old.name) = new.name WHERE old.id != new.id AND taggings.id = t.id")
  11 +
  12 + execute("UPDATE tags SET taggings_count = (SELECT COUNT(*) FROM taggings WHERE taggings.tag_id = tags.id)")
  13 + execute("DELETE FROM tags WHERE taggings_count = 0")
  14 + end
  15 +
  16 + def down
  17 + say 'This migration is irreversible.'
  18 + end
  19 +end
db/migrate/20150507204849_remove_broken_profile_suggestions.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class RemoveBrokenProfileSuggestions < ActiveRecord::Migration
  2 + def up
  3 + execute("DELETE FROM profile_suggestions WHERE suggestion_id NOT IN (SELECT id from profiles)")
  4 + end
  5 +
  6 + def down
  7 + say "this migration can't be reverted"
  8 + end
  9 +end
db/migrate/20150529180110_add_date_format_to_environment.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class AddDateFormatToEnvironment < ActiveRecord::Migration
  2 + def up
  3 + add_column :environments, :date_format, :string, :default => 'month_name_with_year'
  4 + end
  5 +
  6 + def down
  7 + remove_column :environments, :date_format
  8 + end
  9 +end
db/migrate/20150602142030_add_closed_by_to_task.rb 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +class AddClosedByToTask < ActiveRecord::Migration
  2 +
  3 + def change
  4 + add_column :tasks, :closed_by_id, :integer
  5 + end
  6 +
  7 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended to check this file into your version control system. 12 # It's strongly recommended to check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(:version => 20150525101430) do 14 +ActiveRecord::Schema.define(:version => 20150602142030) do
15 15
16 create_table "abuse_reports", :force => true do |t| 16 create_table "abuse_reports", :force => true do |t|
17 t.integer "reporter_id" 17 t.integer "reporter_id"
@@ -320,17 +320,18 @@ ActiveRecord::Schema.define(:version =&gt; 20150525101430) do @@ -320,17 +320,18 @@ ActiveRecord::Schema.define(:version =&gt; 20150525101430) do
320 t.text "design_data" 320 t.text "design_data"
321 t.text "custom_header" 321 t.text "custom_header"
322 t.text "custom_footer" 322 t.text "custom_footer"
323 - t.string "theme", :default => "default", :null => false 323 + t.string "theme", :default => "default", :null => false
324 t.text "terms_of_use_acceptance_text" 324 t.text "terms_of_use_acceptance_text"
325 t.datetime "created_at" 325 t.datetime "created_at"
326 t.datetime "updated_at" 326 t.datetime "updated_at"
327 - t.integer "reports_lower_bound", :default => 0, :null => false 327 + t.integer "reports_lower_bound", :default => 0, :null => false
328 t.string "redirection_after_login", :default => "keep_on_same_page" 328 t.string "redirection_after_login", :default => "keep_on_same_page"
329 t.text "signup_welcome_text" 329 t.text "signup_welcome_text"
330 t.string "languages" 330 t.string "languages"
331 t.string "default_language" 331 t.string "default_language"
332 t.string "noreply_email" 332 t.string "noreply_email"
333 t.string "redirection_after_signup", :default => "keep_on_same_page" 333 t.string "redirection_after_signup", :default => "keep_on_same_page"
  334 + t.string "date_format", :default => "month_name_with_year"
334 end 335 end
335 336
336 create_table "external_feeds", :force => true do |t| 337 create_table "external_feeds", :force => true do |t|
@@ -691,6 +692,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150525101430) do @@ -691,6 +692,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150525101430) do
691 t.integer "image_id" 692 t.integer "image_id"
692 t.boolean "spam", :default => false 693 t.boolean "spam", :default => false
693 t.integer "responsible_id" 694 t.integer "responsible_id"
  695 + t.integer "closed_by_id"
694 end 696 end
695 697
696 add_index "tasks", ["requestor_id"], :name => "index_tasks_on_requestor_id" 698 add_index "tasks", ["requestor_id"], :name => "index_tasks_on_requestor_id"
features/approve_article.feature
@@ -62,7 +62,8 @@ Feature: approve article @@ -62,7 +62,8 @@ Feature: approve article
62 And I press "Spread this" 62 And I press "Spread this"
63 And I follow "Delete" 63 And I follow "Delete"
64 And I confirm the browser dialog 64 And I confirm the browser dialog
65 - When I am logged in as "joaosilva" 65 + And I follow "Logout"
  66 + And I am logged in as "joaosilva"
66 And I go to sample-community's control panel 67 And I go to sample-community's control panel
67 And I follow "Process requests" 68 And I follow "Process requests"
68 And I choose "Reject" 69 And I choose "Reject"
features/balloon.feature
@@ -41,19 +41,19 @@ Feature: balloon @@ -41,19 +41,19 @@ Feature: balloon
41 @selenium 41 @selenium
42 Scenario: I should not see trigger if not enabled on page 42 Scenario: I should not see trigger if not enabled on page
43 Given feature "show_balloon_with_profile_links_when_clicked" is disabled on environment 43 Given feature "show_balloon_with_profile_links_when_clicked" is disabled on environment
44 - When I go to /assets/people 44 + When I go to /search/people
45 Then I should not see "Profile links" 45 Then I should not see "Profile links"
46 46
47 @selenium 47 @selenium
48 Scenario: I should not see trigger by default on page 48 Scenario: I should not see trigger by default on page
49 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment 49 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
50 - When I go to /assets/communities 50 + When I go to /search/communities
51 Then I should not see "Members" 51 Then I should not see "Members"
52 52
53 @selenium 53 @selenium
54 Scenario: I should see balloon when clicked on page trigger 54 Scenario: I should see balloon when clicked on page trigger
55 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment 55 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
56 - And I go to /assets/communities 56 + And I go to /search/communities
57 And display ".community-trigger" 57 And display ".community-trigger"
58 When I follow "Profile links" 58 When I follow "Profile links"
59 Then I should see "Members" 59 Then I should see "Members"
features/browse_enterprises.feature
@@ -13,20 +13,20 @@ Scenario: show all enterprises @@ -13,20 +13,20 @@ Scenario: show all enterprises
13 Given the following enterprises 13 Given the following enterprises
14 | identifier | name | 14 | identifier | name |
15 | shop2 | Fruits Shop | 15 | shop2 | Fruits Shop |
16 - Given I am on /assets/enterprises 16 + Given I am on /search/enterprises
17 Then I should see "Enterprises" 17 Then I should see "Enterprises"
18 And I should see "Shoes Shop" 18 And I should see "Shoes Shop"
19 And I should see "Fruits Shop" 19 And I should see "Fruits Shop"
20 20
21 Scenario: show profile links button 21 Scenario: show profile links button
22 - Given I am on /assets/enterprises 22 + Given I am on /search/enterprises
23 Then I should see "Profile links" within "a.enterprise-trigger" 23 Then I should see "Profile links" within "a.enterprise-trigger"
24 And I should not see "Members" 24 And I should not see "Members"
25 And I should not see "Agenda" 25 And I should not see "Agenda"
26 26
27 @selenium-fixme 27 @selenium-fixme
28 Scenario: show profile links when clicked 28 Scenario: show profile links when clicked
29 - Given I am on /assets/enterprises 29 + Given I am on /search/enterprises
30 When I follow "Profile links" 30 When I follow "Profile links"
31 Then I should see "Products" within "ul.menu-submenu-list" 31 Then I should see "Products" within "ul.menu-submenu-list"
32 And I should see "Members" within "ul.menu-submenu-list" 32 And I should see "Members" within "ul.menu-submenu-list"
@@ -34,7 +34,7 @@ Scenario: show profile links when clicked @@ -34,7 +34,7 @@ Scenario: show profile links when clicked
34 34
35 @selenium-fixme 35 @selenium-fixme
36 Scenario: go to catalog when click on products link 36 Scenario: go to catalog when click on products link
37 - Given I am on /assets/enterprises 37 + Given I am on /search/enterprises
38 When I follow "Profile links" 38 When I follow "Profile links"
39 And I follow "Products" and wait 39 And I follow "Products" and wait
40 Then I should be exactly on /catalog/shop1 40 Then I should be exactly on /catalog/shop1
features/change_appearance.feature
@@ -14,7 +14,7 @@ Feature: Change appearance @@ -14,7 +14,7 @@ Feature: Change appearance
14 And I should not see an element ".box-4" 14 And I should not see an element ".box-4"
15 And I go to joaosilva's control panel 15 And I go to joaosilva's control panel
16 And I follow "Edit Appearance" 16 And I follow "Edit Appearance"
17 - And I follow "Left Top and Right" 17 + And I follow "Top and Side Bars"
18 And I go to joaosilva's control panel 18 And I go to joaosilva's control panel
19 And I follow "Edit sideboxes" 19 And I follow "Edit sideboxes"
20 And I should see an element ".box-4" 20 And I should see an element ".box-4"
features/events.feature
@@ -17,7 +17,7 @@ Feature: events @@ -17,7 +17,7 @@ Feature: events
17 Then I should see "November 2009" within ".current-month" 17 Then I should see "November 2009" within ".current-month"
18 18
19 Scenario: go to next month in global agenda 19 Scenario: go to next month in global agenda
20 - Given I am on /assets/events?year=2009&month=11 20 + Given I am on /search/events?year=2009&month=11
21 When I follow "December" 21 When I follow "December"
22 Then I should see "December 2009" within ".current-month" 22 Then I should see "December 2009" within ".current-month"
23 23
@@ -27,7 +27,7 @@ Feature: events @@ -27,7 +27,7 @@ Feature: events
27 Then I should see "September 2009" within ".current-month" 27 Then I should see "September 2009" within ".current-month"
28 28
29 Scenario: go to previous month in global agenda 29 Scenario: go to previous month in global agenda
30 - Given I am on /assets/events?year=2009&month=11 30 + Given I am on /search/events?year=2009&month=11
31 When I follow "October" 31 When I follow "October"
32 Then I should see "October 2009" within ".current-month" 32 Then I should see "October 2009" within ".current-month"
33 33
@@ -43,7 +43,7 @@ Feature: events @@ -43,7 +43,7 @@ Feature: events
43 43
44 Scenario: go to specific day in global agenda 44 Scenario: go to specific day in global agenda
45 Given I am on the homepage 45 Given I am on the homepage
46 - When I am on /assets/events?year=2009&month=11&day=12 46 + When I am on /search/events?year=2009&month=11&day=12
47 Then I should see "Events for November, 2009" 47 Then I should see "Events for November, 2009"
48 48
49 Scenario: list events for specific day 49 Scenario: list events for specific day
@@ -88,7 +88,7 @@ Feature: events @@ -88,7 +88,7 @@ Feature: events
88 And the following events 88 And the following events
89 | owner | name | start_date | 89 | owner | name | start_date |
90 | josemanuel | Manuel Birthday | 2009-10-24 | 90 | josemanuel | Manuel Birthday | 2009-10-24 |
91 - When I am on /assets/events?year=2009&month=10&day=24 91 + When I am on /search/events?year=2009&month=10&day=24
92 Then I should see "Another Conference" 92 Then I should see "Another Conference"
93 And I should see "Manuel Birthday" 93 And I should see "Manuel Birthday"
94 94
@@ -157,7 +157,7 @@ Feature: events @@ -157,7 +157,7 @@ Feature: events
157 Then I should not see "New events" link 157 Then I should not see "New events" link
158 158
159 Scenario: display environment name in global agenda 159 Scenario: display environment name in global agenda
160 - When I am on /assets/events 160 + When I am on /search/events
161 Then I should see "Colivre.net's Events" 161 Then I should see "Colivre.net's Events"
162 162
163 @selenium 163 @selenium
features/profile_domain.feature
@@ -21,9 +21,7 @@ Feature: domain for profile @@ -21,9 +21,7 @@ Feature: domain for profile
21 Scenario: access profile control panel through profile blocks 21 Scenario: access profile control panel through profile blocks
22 Given I am logged in as "joaosilva" 22 Given I am logged in as "joaosilva"
23 When I go to joaosilva's homepage 23 When I go to joaosilva's homepage
24 - And I follow "Control panel" within ".profile-info-block"  
25 - Then I should see "Joao Silva" within "span.control-panel-title"  
26 - When I follow "Control panel" within ".profile-image-block" 24 + And I follow "Control panel" within ".profile-image-block"
27 Then I should see "Joao Silva" within "span.control-panel-title" 25 Then I should see "Joao Silva" within "span.control-panel-title"
28 26
29 @selenium 27 @selenium
features/profile_search.feature
@@ -36,7 +36,7 @@ Feature: search inside a profile @@ -36,7 +36,7 @@ Feature: search inside a profile
36 | joaosilva | ProfileSearchBlock | 36 | joaosilva | ProfileSearchBlock |
37 When I go to joaosilva's profile 37 When I go to joaosilva's profile
38 And I fill in "q" with "bees" within ".profile-search-block" 38 And I fill in "q" with "bees" within ".profile-search-block"
39 - And I press "Search" 39 + And I press "Search" within ".profile-search-block"
40 Then I should see "bees and butterflies" within ".main-block" 40 Then I should see "bees and butterflies" within ".main-block"
41 41
42 Scenario: not display unpublished articles 42 Scenario: not display unpublished articles
features/register_enterprise.feature
@@ -203,5 +203,5 @@ Feature: register enterprise @@ -203,5 +203,5 @@ Feature: register enterprise
203 203
204 Scenario: a user cant see button to register new enterprise if enterprise_registration disabled 204 Scenario: a user cant see button to register new enterprise if enterprise_registration disabled
205 Given feature "enterprise_registration" is disabled on environment 205 Given feature "enterprise_registration" is disabled on environment
206 - When I am on /assets/enterprises 206 + When I am on /search/enterprises
207 Then I should not see "New enterprise" link 207 Then I should not see "New enterprise" link
features/search_enterprises.feature
@@ -56,7 +56,7 @@ Feature: search enterprises @@ -56,7 +56,7 @@ Feature: search enterprises
56 | owner | name | body | homepage | 56 | owner | name | body | homepage |
57 | shop1 | Shoes home | This is the <i>homepage</i> of Shoes shop! It has a very long and pretty vague description, just so we can test wether the system will correctly create an excerpt of this text. We should probably talk about shoes. | true | 57 | shop1 | Shoes home | This is the <i>homepage</i> of Shoes shop! It has a very long and pretty vague description, just so we can test wether the system will correctly create an excerpt of this text. We should probably talk about shoes. | true |
58 When I search enterprises for "shoes" 58 When I search enterprises for "shoes"
59 - And I choose the search filter "Full" 59 + And I select "Full" from "display"
60 Then I should see "This is the homepage of" within ".search-enterprise-description" 60 Then I should see "This is the homepage of" within ".search-enterprise-description"
61 And I should see "about sho..." within ".search-enterprise-description" 61 And I should see "about sho..." within ".search-enterprise-description"
62 62
@@ -66,7 +66,7 @@ Feature: search enterprises @@ -66,7 +66,7 @@ Feature: search enterprises
66 | identifier | name | description | 66 | identifier | name | description |
67 | shop4 | Clothes shop | This <b>clothes</b> shop also sells shoes! This too has a very long and pretty vague description, just so we can test wether the system will correctly create an excerpt of this text. Clothes are a really important part of our lives. | 67 | shop4 | Clothes shop | This <b>clothes</b> shop also sells shoes! This too has a very long and pretty vague description, just so we can test wether the system will correctly create an excerpt of this text. Clothes are a really important part of our lives. |
68 When I search enterprises for "clothes" 68 When I search enterprises for "clothes"
69 - And I choose the search filter "Full" 69 + And I select "Full" from "display"
70 And I should see "This clothes shop" within ".search-enterprise-description" 70 And I should see "This clothes shop" within ".search-enterprise-description"
71 And I should see "really import..." within ".search-enterprise-description" 71 And I should see "really import..." within ".search-enterprise-description"
72 72
features/step_definitions/noosfero_steps.rb
@@ -94,7 +94,7 @@ Given /^the following blocks$/ do |table| @@ -94,7 +94,7 @@ Given /^the following blocks$/ do |table|
94 owner.boxes<< Box.new 94 owner.boxes<< Box.new
95 owner.boxes.first.blocks << MainBlock.new 95 owner.boxes.first.blocks << MainBlock.new
96 end 96 end
97 - box = owner.boxes.where(:position => 3).first 97 + box = owner.boxes.first
98 klass.constantize.create!(item.merge(:box => box)) 98 klass.constantize.create!(item.merge(:box => box))
99 end 99 end
100 end 100 end
features/suggest_article.feature
@@ -14,9 +14,12 @@ Feature: suggest article @@ -14,9 +14,12 @@ Feature: suggest article
14 14
15 @selenium 15 @selenium
16 Scenario: highlight an article before approval of a suggested article 16 Scenario: highlight an article before approval of a suggested article
17 - Given someone suggested the following article to be published  
18 - | target | article_name | article_body | name | email |  
19 - | sample-community | A suggested article | this is an article about whales | jose | jose@example.org | 17 + Given I am on Sample Community's blog
  18 + And I follow "Suggest an article"
  19 + And I fill in "Title" with "Suggestion"
  20 + And I fill in "Your name" with "Some Guy"
  21 + And I fill in "Email" with "someguy@somewhere.com"
  22 + And I press "Save"
20 When I am logged in as "joaosilva" 23 When I am logged in as "joaosilva"
21 And I go to sample-community's control panel 24 And I go to sample-community's control panel
22 And I follow "Process requests" 25 And I follow "Process requests"
lib/noosfero/plugin.rb
1 require_dependency 'noosfero' 1 require_dependency 'noosfero'
  2 +require 'noosfero/plugin/parent_methods'
2 3
3 class Noosfero::Plugin 4 class Noosfero::Plugin
4 5
@@ -14,13 +15,9 @@ class Noosfero::Plugin @@ -14,13 +15,9 @@ class Noosfero::Plugin
14 15
15 class << self 16 class << self
16 17
17 - attr_writer :should_load 18 + include Noosfero::Plugin::ParentMethods
18 19
19 - # Called for each ActiveRecord class with parents  
20 - # See http://apidock.com/rails/ActiveRecord/ModelSchema/ClassMethods/full_table_name_prefix  
21 - def table_name_prefix  
22 - @table_name_prefix ||= "#{name.to_s.underscore}_"  
23 - end 20 + attr_writer :should_load
24 21
25 def should_load 22 def should_load
26 @should_load.nil? && true || @boot 23 @should_load.nil? && true || @boot
@@ -92,8 +89,14 @@ class Noosfero::Plugin @@ -92,8 +89,14 @@ class Noosfero::Plugin
92 end 89 end
93 end 90 end
94 91
95 - def load_plugin(plugin_name)  
96 - (plugin_name.to_s.camelize + 'Plugin').constantize 92 + def load_plugin_identifier identifier
  93 + klass = identifier.to_s.camelize.constantize
  94 + klass = klass.const_get :Base if klass.class == Module
  95 + klass
  96 + end
  97 +
  98 + def load_plugin public_name
  99 + load_plugin_identifier "#{public_name.to_s.camelize}Plugin"
97 end 100 end
98 101
99 # This is a generic method that initialize any possible filter defined by a 102 # This is a generic method that initialize any possible filter defined by a
@@ -135,7 +138,7 @@ class Noosfero::Plugin @@ -135,7 +138,7 @@ class Noosfero::Plugin
135 filters = [filters] 138 filters = [filters]
136 end 139 end
137 filters.each do |plugin_filter| 140 filters.each do |plugin_filter|
138 - filter_method = (plugin.name.underscore.gsub('/','_') + '_' + plugin_filter[:method_name]).to_sym 141 + filter_method = "#{plugin.identifier}_#{plugin_filter[:method_name]}".to_sym
139 controller_class.send(plugin_filter[:type], filter_method, (plugin_filter[:options] || {})) 142 controller_class.send(plugin_filter[:type], filter_method, (plugin_filter[:options] || {}))
140 controller_class.send(:define_method, filter_method) do 143 controller_class.send(:define_method, filter_method) do
141 instance_exec(&plugin_filter[:block]) if environment.plugin_enabled?(plugin) 144 instance_exec(&plugin_filter[:block]) if environment.plugin_enabled?(plugin)
@@ -167,44 +170,6 @@ class Noosfero::Plugin @@ -167,44 +170,6 @@ class Noosfero::Plugin
167 def all 170 def all
168 @all ||= available_plugins.map{ |dir| (File.basename(dir) + "_plugin").camelize } 171 @all ||= available_plugins.map{ |dir| (File.basename(dir) + "_plugin").camelize }
169 end 172 end
170 -  
171 - def public_name  
172 - self.name.underscore.gsub('_plugin','')  
173 - end  
174 -  
175 - def public_path file = '', relative=false  
176 - File.join "#{if relative then '' else '/' end}plugins", public_name, file  
177 - end  
178 -  
179 - def root_path  
180 - Rails.root.join('plugins', public_name)  
181 - end  
182 -  
183 - def view_path  
184 - File.join(root_path,'views')  
185 - end  
186 -  
187 - # Here the developer should specify the meta-informations that the plugin can  
188 - # inform.  
189 - def plugin_name  
190 - self.name.underscore.humanize  
191 - end  
192 - def plugin_description  
193 - _("No description informed.")  
194 - end  
195 -  
196 - def admin_url  
197 - {:controller => "#{name.underscore}_admin", :action => 'index'}  
198 - end  
199 -  
200 - def has_admin_url?  
201 - File.exists?(File.join(root_path, 'controllers', "#{name.underscore}_admin_controller.rb"))  
202 - end  
203 -  
204 - # -> define grape class used to map resource api provided by the plugin  
205 - def api_mount_points  
206 - []  
207 - end  
208 end 173 end
209 174
210 def expanded_template(file_path, locals = {}) 175 def expanded_template(file_path, locals = {})
lib/noosfero/plugin/manager.rb
@@ -76,7 +76,7 @@ class Noosfero::Plugin::Manager @@ -76,7 +76,7 @@ class Noosfero::Plugin::Manager
76 76
77 def enabled_plugins 77 def enabled_plugins
78 @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin| 78 @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin|
79 - plugin.constantize.new(context) 79 + Noosfero::Plugin.load_plugin_identifier(plugin).new context
80 end 80 end
81 end 81 end
82 82
lib/noosfero/plugin/parent_methods.rb 0 → 100644
@@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
  1 +class Noosfero::Plugin
  2 +
  3 + # Plugins that are defined as modules should extend
  4 + # this module manually, for example:
  5 + # module MyPlugin
  6 + # extend Noosfero::Plugin::ParentMethods
  7 + # end
  8 + module ParentMethods
  9 +
  10 + def identifier
  11 + @identifier ||= (if self.parents.first.instance_of? Module then self.parents.first else self end).name.underscore
  12 + end
  13 +
  14 + def public_name
  15 + @public_name ||= self.identifier.gsub '_plugin', ''
  16 + end
  17 +
  18 + # Here the developer should specify the meta-informations that the plugin can
  19 + # inform.
  20 + def plugin_name
  21 + self.identifier.humanize
  22 + end
  23 + def plugin_description
  24 + _("No description informed.")
  25 + end
  26 +
  27 + # Called for each ActiveRecord model with parents
  28 + # See http://apidock.com/rails/ActiveRecord/ModelSchema/ClassMethods/full_table_name_prefix
  29 + def table_name_prefix
  30 + @table_name_prefix ||= "#{self.identifier}_"
  31 + end
  32 +
  33 + def public_path file = '', relative=false
  34 + File.join "#{if relative then '' else '/' end}plugins", public_name, file
  35 + end
  36 +
  37 + def root_path
  38 + Rails.root.join('plugins', public_name)
  39 + end
  40 +
  41 + def view_path
  42 + File.join(root_path,'views')
  43 + end
  44 +
  45 + def admin_url
  46 + {:controller => "#{self.identifier}_admin", :action => 'index'}
  47 + end
  48 +
  49 + def has_admin_url?
  50 + File.exists?(File.join(root_path, 'controllers', "#{self.identifier}_admin_controller.rb"))
  51 + end
  52 +
  53 + # -> define grape class used to map resource api provided by the plugin
  54 + def api_mount_points
  55 + []
  56 + end
  57 +
  58 + def controllers
  59 + @controllers ||= Dir.glob("#{self.root_path}/controllers/*/*").map do |controller_file|
  60 + next unless controller_file =~ /_controller.rb$/
  61 + controller = File.basename(controller_file).gsub(/.rb$/, '').camelize
  62 + end.compact
  63 + end
  64 +
  65 + end
  66 +
  67 +end
lib/noosfero/vote_ext.rb 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +require_dependency 'models/vote'
  2 +
  3 +class Vote
  4 +
  5 + validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id]
  6 +
  7 +end
lib/short_filename.rb
1 module ShortFilename 1 module ShortFilename
2 2
3 def short_filename(filename, limit_chars = 43) 3 def short_filename(filename, limit_chars = 43)
4 - return filename if filename.size <= limit_chars  
5 extname = File.extname(filename) 4 extname = File.extname(filename)
6 basename = File.basename(filename,extname) 5 basename = File.basename(filename,extname)
  6 + return shrink(basename, extname, limit_chars) + extname
  7 + end
  8 +
  9 + def short_filename_upper_ext(filename, limit_chars = 43)
  10 + extname = File.extname(filename)
  11 + display_name = shrink(File.basename(filename, extname), extname, limit_chars)
  12 + return extname.present? ? (display_name + ' - ' + extname.upcase.delete(".")) : display_name
  13 + end
  14 +
  15 + def shrink(filename, extname, limit_chars)
  16 + return filename if filename.size <= limit_chars
7 str_complement = '(...)' 17 str_complement = '(...)'
8 - return basename[0..(limit_chars - extname.size - str_complement.size - 1)] + str_complement + extname 18 + return filename[0..(limit_chars - extname.size - str_complement.size - 1)] + str_complement
9 end 19 end
10 20
11 end 21 end
plugins/comment_classification/views/comment_classification_plugin_myprofile/add_status.html.erb
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 <ul> 13 <ul>
14 <% @comment.comment_classification_plugin_comment_status_users.each do |relation| %> 14 <% @comment.comment_classification_plugin_comment_status_users.each do |relation| %>
15 <li> 15 <li>
16 - <%= _("<i>%{user}</i> added the status <i>%{status_name}</i> at <i>%{created_at}</i>.") % { :user => relation.profile.name, :status_name => relation.status.name, :created_at => time_ago_as_sentence(relation.created_at)} %> 16 + <%= _("<i>%{user}</i> added the status <i>%{status_name}</i> at <i>%{created_at}</i>.") % { :user => relation.profile.name, :status_name => relation.status.name, :created_at => time_ago_in_words(relation.created_at)} %>
17 <% unless relation.reason.blank? %> 17 <% unless relation.reason.blank? %>
18 <p><%= _("<i>Reason:</i> %s") % relation.reason %></p> 18 <p><%= _("<i>Reason:</i> %s") % relation.reason %></p>
19 <% end %> 19 <% end %>
plugins/custom_forms/views/custom_forms_plugin_profile/show.html.erb
@@ -14,8 +14,8 @@ @@ -14,8 +14,8 @@
14 14
15 <%= form_for :submission do |f| %> 15 <%= form_for :submission do |f| %>
16 <% if !user %> 16 <% if !user %>
17 - <%= required labelled_form_field _('Author name'), text_field_tag(:author_name, @submission.author_name) %>  
18 - <%= required labelled_form_field _('Author email'), text_field_tag(:author_email, @submission.author_email) %> 17 + <%= required labelled_form_field _('Name'), text_field_tag(:author_name, @submission.author_name) %>
  18 + <%= required labelled_form_field _('Email'), text_field_tag(:author_email, @submission.author_email) %>
19 <% end %> 19 <% end %>
20 20
21 <%= render :partial => 'shared/form_submission', :locals => {:f => f} %> 21 <%= render :partial => 'shared/form_submission', :locals => {:f => f} %>
plugins/metadata/lib/metadata_plugin.rb
@@ -23,7 +23,7 @@ class MetadataPlugin &lt; Noosfero::Plugin @@ -23,7 +23,7 @@ class MetadataPlugin &lt; Noosfero::Plugin
23 }, 23 },
24 content_viewer: { 24 content_viewer: {
25 variable: proc do 25 variable: proc do
26 - if profile and profile.home_page_id == @page.id 26 + if profile and @page and profile.home_page_id == @page.id
27 @profile 27 @profile
28 elsif @page.respond_to? :encapsulated_file 28 elsif @page.respond_to? :encapsulated_file
29 @page.encapsulated_file 29 @page.encapsulated_file
plugins/metadata/test/functional/content_viewer_controller_test.rb
@@ -48,4 +48,13 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -48,4 +48,13 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
48 assert_tag tag: 'meta', attributes: { property: 'og:image', content: /\/images\/x.png/ } 48 assert_tag tag: 'meta', attributes: { property: 'og:image', content: /\/images\/x.png/ }
49 end 49 end
50 50
  51 + should 'render not_found page properly' do
  52 + assert_equal false, Article.exists?(:slug => 'non-existing-page')
  53 + assert_nothing_raised do
  54 + get :view_page, profile: profile.identifier, page: [ 'non-existing-page' ]
  55 + assert_response 404 # not found
  56 + assert_template 'not_found'
  57 + end
  58 + end
  59 +
51 end 60 end
plugins/vote/lib/ext/article.rb
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -require_dependency 'article'  
2 -  
3 -class Article  
4 -  
5 - acts_as_voteable  
6 -  
7 -end  
plugins/vote/lib/ext/comment.rb
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -require_dependency 'comment'  
2 -  
3 -class Comment  
4 -  
5 - acts_as_voteable  
6 -  
7 -end  
plugins/vote/lib/ext/person.rb
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -require_dependency 'person'  
2 -  
3 -class Person  
4 -  
5 - acts_as_voter  
6 -  
7 -end  
plugins/vote/lib/ext/vote.rb
@@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
1 -require_dependency 'models/vote'  
2 -  
3 -class Vote  
4 -  
5 - validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id]  
6 -  
7 -end  
plugins/vote/test/unit/article_test.rb
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -require 'test_helper'  
2 -  
3 -class ArticleTest < ActiveSupport::TestCase  
4 -  
5 - def setup  
6 - @profile = create_user('testing').person  
7 - end  
8 -  
9 - attr_reader :profile  
10 -  
11 - should 'vote in a article' do  
12 - article = create(Article, :name => 'Test', :profile => profile, :last_changed_by => nil)  
13 - profile.vote(article, 5)  
14 - assert_equal 1, article.voters_who_voted.length  
15 - assert_equal 5, article.votes_total  
16 - end  
17 -  
18 - should 'be able to remove a voted article' do  
19 - article = create(Article, :name => 'Test', :profile => profile, :last_changed_by => nil)  
20 - profile.vote(article, 5)  
21 - article.destroy  
22 - end  
23 -  
24 -end  
plugins/vote/test/unit/comment_test.rb
@@ -1,59 +0,0 @@ @@ -1,59 +0,0 @@
1 -require 'test_helper'  
2 -  
3 -class CommentTest < ActiveSupport::TestCase  
4 -  
5 - should 'vote in a comment' do  
6 - comment = create_comment  
7 - person = create_user('voter').person  
8 - person.vote(comment, 5)  
9 - assert_equal 1, comment.voters_who_voted.length  
10 - assert_equal 5, comment.votes_total  
11 - end  
12 -  
13 - should 'like a comment' do  
14 - comment = create_comment  
15 - person = create_user('voter').person  
16 - assert !comment.voted_by?(person, true)  
17 - person.vote_for(comment)  
18 - assert comment.voted_by?(person, true)  
19 - assert !comment.voted_by?(person, false)  
20 - end  
21 -  
22 - should 'count voters for' do  
23 - comment = create_comment  
24 - person = create_user('voter').person  
25 - person2 = create_user('voter2').person  
26 - person3 = create_user('voter3').person  
27 - person.vote_for(comment)  
28 - person2.vote_for(comment)  
29 - person3.vote_against(comment)  
30 - assert_equal 2, comment.votes_for  
31 - end  
32 -  
33 - should 'count votes againts' do  
34 - comment = create_comment  
35 - person = create_user('voter').person  
36 - person2 = create_user('voter2').person  
37 - person3 = create_user('voter3').person  
38 - person.vote_against(comment)  
39 - person2.vote_against(comment)  
40 - person3.vote_for(comment)  
41 - assert_equal 2, comment.votes_against  
42 - end  
43 -  
44 - should 'be able to remove a voted comment' do  
45 - comment = create_comment  
46 - person = create_user('voter').person  
47 - person.vote(comment, 5)  
48 - comment.destroy  
49 - end  
50 -  
51 - private  
52 -  
53 - def create_comment(args = {})  
54 - owner = create_user('testuser').person  
55 - article = create(TextileArticle, :profile_id => owner.id)  
56 - create(Comment, { :name => 'foo', :email => 'foo@example.com', :source => article }.merge(args))  
57 - end  
58 -  
59 -end  
plugins/vote/test/unit/person_test.rb
@@ -1,134 +0,0 @@ @@ -1,134 +0,0 @@
1 -require 'test_helper'  
2 -  
3 -class PersonTest < ActiveSupport::TestCase  
4 -  
5 - should 'vote in a comment with value greater than 1' do  
6 - comment = fast_create(Comment)  
7 - person = fast_create(Person)  
8 -  
9 - person.vote(comment, 5)  
10 - assert_equal 1, person.vote_count  
11 - assert_equal 5, person.votes.first.vote  
12 - assert person.voted_on?(comment)  
13 - end  
14 -  
15 - should 'vote in a comment with value lesser than -1' do  
16 - comment = fast_create(Comment)  
17 - person = fast_create(Person)  
18 -  
19 - person.vote(comment, -5)  
20 - assert_equal 1, person.vote_count  
21 - assert_equal -5, person.votes.first.vote  
22 - end  
23 -  
24 - should 'vote for a comment' do  
25 - comment = fast_create(Comment)  
26 - person = fast_create(Person)  
27 -  
28 - assert !person.voted_for?(comment)  
29 - person.vote_for(comment)  
30 - assert person.voted_for?(comment)  
31 - assert !person.voted_against?(comment)  
32 - end  
33 -  
34 - should 'vote against a comment' do  
35 - comment = fast_create(Comment)  
36 - person = fast_create(Person)  
37 -  
38 - assert !person.voted_against?(comment)  
39 - person.vote_against(comment)  
40 - assert !person.voted_for?(comment)  
41 - assert person.voted_against?(comment)  
42 - end  
43 -  
44 - should 'do not vote against a comment twice' do  
45 - comment = fast_create(Comment)  
46 - person = fast_create(Person)  
47 -  
48 - assert person.vote_against(comment)  
49 - assert !person.vote_against(comment)  
50 - end  
51 -  
52 - should 'do not vote for a comment twice' do  
53 - comment = fast_create(Comment)  
54 - person = fast_create(Person)  
55 -  
56 - assert person.vote_for(comment)  
57 - assert !person.vote_for(comment)  
58 - end  
59 -  
60 - should 'not vote against a voted for comment' do  
61 - comment = fast_create(Comment)  
62 - person = fast_create(Person)  
63 -  
64 - person.vote_for(comment)  
65 - person.vote_against(comment)  
66 - assert person.voted_for?(comment)  
67 - assert !person.voted_against?(comment)  
68 - end  
69 -  
70 - should 'not vote for a voted against comment' do  
71 - comment = fast_create(Comment)  
72 - person = fast_create(Person)  
73 -  
74 - person.vote_against(comment)  
75 - person.vote_for(comment)  
76 - assert !person.voted_for?(comment)  
77 - assert person.voted_against?(comment)  
78 - end  
79 -  
80 - should 'undo a vote for a comment' do  
81 - comment = fast_create(Comment)  
82 - person = fast_create(Person)  
83 -  
84 - person.vote_for(comment)  
85 - assert person.voted_for?(comment)  
86 - person.votes.for_voteable(comment).destroy_all  
87 - assert !person.voted_for?(comment)  
88 - end  
89 -  
90 - should 'count comments voted' do  
91 - comment = fast_create(Comment)  
92 - person = fast_create(Person)  
93 -  
94 - comment2 = fast_create(Comment)  
95 - comment3 = fast_create(Comment)  
96 - person.vote_for(comment)  
97 - person.vote_for(comment2)  
98 - person.vote_against(comment3)  
99 - assert_equal 3, person.vote_count  
100 - assert_equal 2, person.vote_count(true)  
101 - assert_equal 1, person.vote_count(false)  
102 - end  
103 -  
104 - should 'vote in a article with value greater than 1' do  
105 - article = fast_create(Article)  
106 - person = fast_create(Person)  
107 -  
108 - person.vote(article, 5)  
109 - assert_equal 1, person.vote_count  
110 - assert_equal 5, person.votes.first.vote  
111 - assert person.voted_on?(article)  
112 - end  
113 -  
114 - should 'vote for a article' do  
115 - article = fast_create(Article)  
116 - person = fast_create(Person)  
117 -  
118 - assert !person.voted_for?(article)  
119 - person.vote_for(article)  
120 - assert person.voted_for?(article)  
121 - assert !person.voted_against?(article)  
122 - end  
123 -  
124 - should 'vote against a article' do  
125 - article = fast_create(Article)  
126 - person = fast_create(Person)  
127 -  
128 - assert !person.voted_against?(article)  
129 - person.vote_against(article)  
130 - assert !person.voted_for?(article)  
131 - assert person.voted_against?(article)  
132 - end  
133 -  
134 -end  
po/pt/noosfero.po
@@ -13,10 +13,10 @@ msgid &quot;&quot; @@ -13,10 +13,10 @@ msgid &quot;&quot;
13 msgstr "" 13 msgstr ""
14 "Project-Id-Version: 1.1-166-gaf47713\n" 14 "Project-Id-Version: 1.1-166-gaf47713\n"
15 "POT-Creation-Date: 2015-06-01 17:26-0300\n" 15 "POT-Creation-Date: 2015-06-01 17:26-0300\n"
16 -"PO-Revision-Date: 2015-03-29 01:47+0200\n"  
17 -"Last-Translator: daniel <dtygel@eita.org.br>\n"  
18 -"Language-Team: Portuguese <https://hosted.weblate.org/projects/noosfero/"  
19 -"noosfero/pt/>\n" 16 +"PO-Revision-Date: 2015-06-02 19:44+0200\n"
  17 +"Last-Translator: Arthur Del Esposte <arthurmde@gmail.com>\n"
  18 +"Language-Team: Portuguese "
  19 +"<https://hosted.weblate.org/projects/noosfero/noosfero/pt/>\n"
20 "Language: pt\n" 20 "Language: pt\n"
21 "MIME-Version: 1.0\n" 21 "MIME-Version: 1.0\n"
22 "Content-Type: text/plain; charset=UTF-8\n" 22 "Content-Type: text/plain; charset=UTF-8\n"
@@ -378,9 +378,8 @@ msgid &quot;Manage environment users&quot; @@ -378,9 +378,8 @@ msgid &quot;Manage environment users&quot;
378 msgstr "Gerenciar usuários do ambiente" 378 msgstr "Gerenciar usuários do ambiente"
379 379
380 #: app/models/environment.rb:32 380 #: app/models/environment.rb:32
381 -#, fuzzy  
382 msgid "Manage environment organizations" 381 msgid "Manage environment organizations"
383 -msgstr "Gerenciar ambiente de validadores" 382 +msgstr "Gerenciar organizações do ambiente"
384 383
385 #: app/models/environment.rb:33 384 #: app/models/environment.rb:33
386 msgid "Manage environment templates" 385 msgid "Manage environment templates"
@@ -697,14 +696,12 @@ msgstr &quot;&quot; @@ -697,14 +696,12 @@ msgstr &quot;&quot;
697 "podem ser feitas." 696 "podem ser feitas."
698 697
699 #: app/models/forum.rb:38 698 #: app/models/forum.rb:38
700 -#, fuzzy  
701 msgid "Logged users" 699 msgid "Logged users"
702 -msgstr "Identificado(a) como %s" 700 +msgstr "Usuários logados"
703 701
704 #: app/models/forum.rb:41 702 #: app/models/forum.rb:41
705 -#, fuzzy  
706 msgid "Me" 703 msgid "Me"
707 -msgstr "Masculino" 704 +msgstr "Eu"
708 705
709 #: app/models/forum.rb:42 app/models/block.rb:250 706 #: app/models/forum.rb:42 app/models/block.rb:250
710 #: app/helpers/application_helper.rb:563 707 #: app/helpers/application_helper.rb:563
@@ -712,9 +709,8 @@ msgid &quot;Friends&quot; @@ -712,9 +709,8 @@ msgid &quot;Friends&quot;
712 msgstr "Amigos" 709 msgstr "Amigos"
713 710
714 #: app/models/forum.rb:45 711 #: app/models/forum.rb:45
715 -#, fuzzy  
716 msgid "Administrators" 712 msgid "Administrators"
717 -msgstr "Administração" 713 +msgstr "Administradores"
718 714
719 #: app/models/forum.rb:46 app/models/block.rb:250 715 #: app/models/forum.rb:46 app/models/block.rb:250
720 #: app/helpers/profile_helper.rb:43 app/helpers/application_helper.rb:571 716 #: app/helpers/profile_helper.rb:43 app/helpers/application_helper.rb:571
@@ -1057,9 +1053,9 @@ msgid &quot;&quot; @@ -1057,9 +1053,9 @@ msgid &quot;&quot;
1057 "User \"%{user}\" just requested to register. You have to approve or reject " 1053 "User \"%{user}\" just requested to register. You have to approve or reject "
1058 "it through the \"Pending Validations\" section in your control panel.\n" 1054 "it through the \"Pending Validations\" section in your control panel.\n"
1059 msgstr "" 1055 msgstr ""
1060 -"O usuário \"%{user}\" requisitou a criação da comunidade %{community}. Você "  
1061 -"tem que aprová-lo ou rejeitá-lo através da seção \"Validações Pendentes\" no "  
1062 -"seu painel de controle.\n" 1056 +"O usuário \"%{user}\" pediu para cadastrar-se. Você tem que aprová-lo ou "
  1057 +"rejeitá-lo através da seção \"Validações Pendentes\" no seu painel de "
  1058 +"controle.\n"
1063 1059
1064 #: app/models/user.rb:10 app/models/change_password.rb:8 1060 #: app/models/user.rb:10 app/models/change_password.rb:8
1065 #: app/views/invite/_select_address_book.html.erb:34 1061 #: app/views/invite/_select_address_book.html.erb:34
@@ -1831,14 +1827,12 @@ msgid &quot;Article suggestion&quot; @@ -1831,14 +1827,12 @@ msgid &quot;Article suggestion&quot;
1831 msgstr "Sugestão de artigo" 1827 msgstr "Sugestão de artigo"
1832 1828
1833 #: app/models/suggest_article.rb:64 1829 #: app/models/suggest_article.rb:64
1834 -#, fuzzy  
1835 msgid "%{requestor} suggested the publication of the article: %{subject}." 1830 msgid "%{requestor} suggested the publication of the article: %{subject}."
1836 -msgstr "%{sender} sugeriu a publicação do artigo: %{subject}." 1831 +msgstr "%{requestor} sugeriu a publicação do artigo: %{subject}."
1837 1832
1838 #: app/models/suggest_article.rb:77 1833 #: app/models/suggest_article.rb:77
1839 -#, fuzzy  
1840 msgid "%{requestor} suggested the publication of the article: %{article}." 1834 msgid "%{requestor} suggested the publication of the article: %{article}."
1841 -msgstr "%{sender} sugeriu a publicação do artigo %{article}." 1835 +msgstr "%{requestor} sugeriu a publicação do artigo %{article}."
1842 1836
1843 #: app/models/rss_feed.rb:6 1837 #: app/models/rss_feed.rb:6
1844 msgid "RssFeed" 1838 msgid "RssFeed"
@@ -2221,11 +2215,11 @@ msgstr &quot;Não logado&quot; @@ -2221,11 +2215,11 @@ msgstr &quot;Não logado&quot;
2221 2215
2222 #: app/models/block.rb:256 2216 #: app/models/block.rb:256
2223 msgid "Can be modified" 2217 msgid "Can be modified"
2224 -msgstr "" 2218 +msgstr "Pode ser modificada"
2225 2219
2226 #: app/models/block.rb:257 2220 #: app/models/block.rb:257
2227 msgid "Cannot be modified" 2221 msgid "Cannot be modified"
2228 -msgstr "" 2222 +msgstr "Não pode ser modificada"
2229 2223
2230 #: app/models/block.rb:263 2224 #: app/models/block.rb:263
2231 msgid "Can be moved" 2225 msgid "Can be moved"
@@ -2563,9 +2557,8 @@ msgid &quot;Public&quot; @@ -2563,9 +2557,8 @@ msgid &quot;Public&quot;
2563 msgstr "Público" 2557 msgstr "Público"
2564 2558
2565 #: app/helpers/application_helper.rb:944 2559 #: app/helpers/application_helper.rb:944
2566 -#, fuzzy  
2567 msgid "Clone %s" 2560 msgid "Clone %s"
2568 -msgstr "Clonar" 2561 +msgstr "Clonar %s"
2569 2562
2570 #: app/helpers/application_helper.rb:958 2563 #: app/helpers/application_helper.rb:958
2571 msgid "Online Manual" 2564 msgid "Online Manual"
@@ -2842,21 +2835,20 @@ msgid &quot;See all connections&quot; @@ -2842,21 +2835,20 @@ msgid &quot;See all connections&quot;
2842 msgstr "Ver todas as conexões" 2835 msgstr "Ver todas as conexões"
2843 2836
2844 #: app/helpers/application_helper.rb:1518 2837 #: app/helpers/application_helper.rb:1518
2845 -#, fuzzy  
2846 msgid "Full screen" 2838 msgid "Full screen"
2847 -msgstr "Post completo" 2839 +msgstr "Tela cheia"
2848 2840
2849 #: app/helpers/application_helper.rb:1523 2841 #: app/helpers/application_helper.rb:1523
2850 msgid "Go to full screen mode" 2842 msgid "Go to full screen mode"
2851 -msgstr "" 2843 +msgstr "Ir para o modo tela cheia"
2852 2844
2853 #: app/helpers/application_helper.rb:1526 2845 #: app/helpers/application_helper.rb:1526
2854 msgid "Exit full screen" 2846 msgid "Exit full screen"
2855 -msgstr "" 2847 +msgstr "Sair da tela cheia"
2856 2848
2857 #: app/helpers/application_helper.rb:1532 2849 #: app/helpers/application_helper.rb:1532
2858 msgid "Exit full screen mode" 2850 msgid "Exit full screen mode"
2859 -msgstr "" 2851 +msgstr "Sair do modo tela cheia"
2860 2852
2861 #: app/helpers/manage_products_helper.rb:156 2853 #: app/helpers/manage_products_helper.rb:156
2862 #: app/views/manage_products/_display_category.html.erb:3 2854 #: app/views/manage_products/_display_category.html.erb:3
@@ -2988,9 +2980,8 @@ msgid &quot;search in all categories&quot; @@ -2988,9 +2980,8 @@ msgid &quot;search in all categories&quot;
2988 msgstr "procurar em todas as categorias" 2980 msgstr "procurar em todas as categorias"
2989 2981
2990 #: app/helpers/search_helper.rb:158 2982 #: app/helpers/search_helper.rb:158
2991 -#, fuzzy  
2992 msgid "Choose a template" 2983 msgid "Choose a template"
2993 -msgstr "O modelo \"%s\"" 2984 +msgstr "Escolha um template"
2994 2985
2995 #: app/helpers/boxes_helper.rb:106 2986 #: app/helpers/boxes_helper.rb:106
2996 msgid "This block is invisible. Your visitors will not see it." 2987 msgid "This block is invisible. Your visitors will not see it."
@@ -4081,9 +4072,8 @@ msgid &quot;Community fields not updated successfully.&quot; @@ -4081,9 +4072,8 @@ msgid &quot;Community fields not updated successfully.&quot;
4081 msgstr "Campos de comunidade não atualizados com sucesso." 4072 msgstr "Campos de comunidade não atualizados com sucesso."
4082 4073
4083 #: app/controllers/admin/organizations_controller.rb:7 4074 #: app/controllers/admin/organizations_controller.rb:7
4084 -#, fuzzy  
4085 msgid "Organization profiles" 4075 msgid "Organization profiles"
4086 -msgstr "Método de Aprovação de Organização" 4076 +msgstr "Perfis de organizações"
4087 4077
4088 #: app/controllers/admin/organizations_controller.rb:9 4078 #: app/controllers/admin/organizations_controller.rb:9
4089 #: app/views/tasks/index.html.erb:7 app/views/tasks/index.html.erb:34 4079 #: app/views/tasks/index.html.erb:7 app/views/tasks/index.html.erb:34
@@ -4093,9 +4083,8 @@ msgid &quot;All&quot; @@ -4093,9 +4083,8 @@ msgid &quot;All&quot;
4093 msgstr "Todos" 4083 msgstr "Todos"
4094 4084
4095 #: app/controllers/admin/organizations_controller.rb:33 4085 #: app/controllers/admin/organizations_controller.rb:33
4096 -#, fuzzy  
4097 msgid "%s enabled" 4086 msgid "%s enabled"
4098 -msgstr "%s não foi habilitado." 4087 +msgstr "%s habilitado"
4099 4088
4100 #: app/controllers/admin/organizations_controller.rb:35 4089 #: app/controllers/admin/organizations_controller.rb:35
4101 #, fuzzy 4090 #, fuzzy
@@ -4103,9 +4092,8 @@ msgid &quot;%s could not be enabled&quot; @@ -4103,9 +4092,8 @@ msgid &quot;%s could not be enabled&quot;
4103 msgstr "%s não pode ser enviado" 4092 msgstr "%s não pode ser enviado"
4104 4093
4105 #: app/controllers/admin/organizations_controller.rb:42 4094 #: app/controllers/admin/organizations_controller.rb:42
4106 -#, fuzzy  
4107 msgid "%s disabled" 4095 msgid "%s disabled"
4108 -msgstr "Desabilitado" 4096 +msgstr "%s desabilitado"
4109 4097
4110 #: app/controllers/admin/organizations_controller.rb:44 4098 #: app/controllers/admin/organizations_controller.rb:44
4111 #, fuzzy 4099 #, fuzzy
@@ -4568,9 +4556,8 @@ msgid &quot;Files&quot; @@ -4568,9 +4556,8 @@ msgid &quot;Files&quot;
4568 msgstr "Arquivos" 4556 msgstr "Arquivos"
4569 4557
4570 #: app/controllers/my_profile/profile_roles_controller.rb:52 4558 #: app/controllers/my_profile/profile_roles_controller.rb:52
4571 -#, fuzzy  
4572 msgid "Role successfuly removed!" 4559 msgid "Role successfuly removed!"
4573 -msgstr "Produto removido com sucesso" 4560 +msgstr "Papel removido com sucesso!"
4574 4561
4575 #: app/controllers/my_profile/profile_roles_controller.rb:54 4562 #: app/controllers/my_profile/profile_roles_controller.rb:54
4576 #, fuzzy 4563 #, fuzzy
@@ -4579,7 +4566,7 @@ msgstr &quot;Falhou em criar papel&quot; @@ -4579,7 +4566,7 @@ msgstr &quot;Falhou em criar papel&quot;
4579 4566
4580 #: app/controllers/my_profile/profile_roles_controller.rb:85 4567 #: app/controllers/my_profile/profile_roles_controller.rb:85
4581 msgid "Error" 4568 msgid "Error"
4582 -msgstr "" 4569 +msgstr "Erro"
4583 4570
4584 #: app/controllers/my_profile/tasks_controller.rb:28 4571 #: app/controllers/my_profile/tasks_controller.rb:28
4585 #, fuzzy 4572 #, fuzzy
public/designs/icons/tango/style.css
@@ -116,6 +116,107 @@ @@ -116,6 +116,107 @@
116 .icon-clock { background-image: url(Tango/16x16/actions/appointment.png) } 116 .icon-clock { background-image: url(Tango/16x16/actions/appointment.png) }
117 .icon-fullscreen { background-image: url(Tango/16x16/actions/view-fullscreen.png) } 117 .icon-fullscreen { background-image: url(Tango/16x16/actions/view-fullscreen.png) }
118 118
  119 +/******************BIG ICONS************************/
  120 +.bigicon-embed { background-image: url(Tango/scalable/apps/utilities-terminal.svg) }
  121 +.bigicon-edit { background-image: url(Tango/scalable/apps/text-editor.svg) }
  122 +.bigicon-undo { background-image: url(Tango/scalable/actions/edit-undo.svg) }
  123 +.bigicon-home { background-image: url(Tango/scalable/actions/go-home.svg) }
  124 +.bigicon-home-not { background-image: url(mod/scalable/actions/go-home-not.svg) }
  125 +.bigicon-new,
  126 +.bigicon-suggest { background-image: url(Tango/scalable/actions/filenew.svg) }
  127 +.bigicon-close { background-image: url(Tango/scalable/actions/gtk-cancel.svg) }
  128 +.bigicon-newfolder { background-image: url(Tango/scalable/actions/folder-new.svg) }
  129 +.bigicon-folder { background-image: url(Tango/scalable/places/folder.svg) }
  130 +.bigicon-parent-folder { background-image: url(Tango/scalable/places/folder_home.svg) }
  131 +.bigicon-newblog { background-image: url(mod/scalable/apps/text-editor.svg) }
  132 +.bigicon-blog { background-image: url(mod/scalable/apps/text-editor.svg) }
  133 +.bigicon-save { background-image: url(Tango/scalable/actions/filesave.svg) }
  134 +.bigicon-send { background-image: url(Tango/scalable/actions/stock_mail-forward.svg) }
  135 +.bigicon-cancel { background-image: url(Tango/scalable/actions/gtk-cancel.svg) }
  136 +.bigicon-person { background-image: url(Tango/scalable/apps/system-config-users.svg) }
  137 +.bigicon-product { background-image: url(Tango/scalable/mimetypes/package.svg) }
  138 +.bigicon-delete { background-image: url(Tango/scalable/places/user-trash.svg) }
  139 +.bigicon-back { background-image: url(Tango/scalable/actions/back.svg) }
  140 +.bigicon-next { background-image: url(Tango/scalable/actions/go-next.svg) }
  141 +.bigicon-add { background-image: url(Tango/scalable/actions/add.svg) }
  142 +.bigicon-remove { background-image: url(Tango/scalable/actions/gtk-remove.svg) }
  143 +.bigicon-more { background-image: url(Tango/scalable/actions/add.svg) }
  144 +.bigicon-up { background-image: url(Tango/scalable/actions/go-up.svg) }
  145 +.bigicon-down { background-image: url(Tango/scalable/actions/go-down.svg) }
  146 +.bigicon-left { background-image: url(Tango/scalable/actions/go-previous.svg) }
  147 +.bigicon-right { background-image: url(Tango/scalable/actions/go-next.svg) }
  148 +.bigicon-up-disabled { background-image: url(Tango/scalable/actions/go-up.svg); opacity: 0.25; filter:alpha(opacity=25); }
  149 +.bigicon-down-disabled { background-image: url(Tango/scalable/actions/go-down.svg); opacity: 0.25; filter:alpha(opacity=25); }
  150 +.bigicon-left-disabled { background-image: url(Tango/scalable/actions/go-previous.svg); opacity: 0.25; filter:alpha(opacity=25); }
  151 +.bigicon-right-disabled { background-image: url(Tango/scalable/actions/go-next.svg); opacity: 0.25; filter:alpha(opacity=25); }
  152 +.bigicon-up-red { background-image: url(mod/scalable/actions/go-up-red.svg) }
  153 +.bigicon-forward { background-image: url(Tango/scalable/actions/go-next.svg) }
  154 +.bigicon-search { background-image: url(Tango/scalable/actions/search.svg) }
  155 +.bigicon-ok { background-image: url(Tango/scalable/actions/media-playback-start.svg) }
  156 +.bigicon-login { background-image: url(mod/scalable/actions/log-in.svg) }
  157 +.bigicon-help { background-image: url(Tango/scalable/apps/gnome-help.svg) }
  158 +.bigicon-help32on { background-image: url(Tango/scalable/apps/gnome-help.svg) }
  159 +.bigicon-help32off { background-image: url(mod/scalable/apps/gnome-help-red.svg) }
  160 +.bigicon-spread { background-image: url(mod/scalable/actions/spread.svg) }
  161 +.bigicon-todo { background-image: url(Tango/scalable/actions/stock_paste.svg) }
  162 +.bigicon-eyes { background-image: url(Tango/scalable/actions/find.svg) }
  163 +.bigicon-menu-home { background-image: url(Tango/scalable/actions/go-home.svg) }
  164 +.bigicon-menu-product { background-image: url(Tango/scalable/mimetypes/package.svg) }
  165 +.bigicon-menu-enterprise { background-image: url(Tango/scalable/actions/go-home.svg) }
  166 +.bigicon-menu-community { background-image: url(Tango/scalable/apps/system-config-users.svg) }
  167 +.bigicon-menu-ctrl-panel { background-image: url(Tango/scalable/categories/preferences-desktop.svg) }
  168 +.bigicon-menu-admin { background-image: url(Tango/scalable/categories/preferences-system.svg) }
  169 +.bigicon-menu-my-groups { background-image: url(Tango/scalable/apps/system-config-users.svg) }
  170 +.bigicon-menu-login { background-image: url(mod/scalable/actions/log-in.svg) }
  171 +.bigicon-menu-logout { background-image: url(mod/scalable/actions/log-out.svg) }
  172 +.bigicon-menu-search { background-image: url(Tango/scalable/actions/search.svg) }
  173 +.bigicon-menu-events { background-image: url(Tango/scalable/mimetypes/stock_calendar.svg) }
  174 +.bigicon-event { background-image: url(Tango/scalable/mimetypes/stock_calendar.svg) }
  175 +.bigicon-newevent { background-image: url(Tango/scalable/mimetypes/stock_calendar.svg) }
  176 +.bigicon-menu-articles { background-image: url(Tango/scalable/apps/text-editor.svg) }
  177 +.bigicon-menu-people { background-image: url(mod/scalable/apps/user.svg) }
  178 +.bigicon-menu-mail { background-image: url(Tango/scalable/apps/email.svg) }
  179 +.bigicon-upload-file { background-image: url(Tango/scalable/actions/filesave.svg) }
  180 +.bigicon-newupload-file { background-image: url(Tango/scalable/actions/filesave.svg) }
  181 +.bigicon-slideshow { background-image: url(Tango/scalable/mimetypes/x-office-presentation.svg) }
  182 +.bigicon-photos { background-image: url(Tango/scalable/devices/camera-photo.svg) }
  183 +.bigicon-vertical-toggle { background-image: url(Tango/scalable/actions/mail-send-receive.svg) }
  184 +.bigicon-text-html { background-image: url(Tango/scalable/mimetypes/text-html.svg) }
  185 +.bigicon-text-plain { background-image: url(Tango/scalable/mimetypes/text-x-generic.svg) }
  186 +.bigicon-image-svg-xml { background-image: url(Tango/scalable/mimetypes/image-x-generic.svg) }
  187 +.bigicon-application-octet-stream { background-image: url(Tango/scalable/mimetypes/binary.svg) }
  188 +.bigicon-application-x-gzip { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-x-gzip.svg) }
  189 +.bigicon-application-postscript { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-postscript.svg) }
  190 +.bigicon-application-pdf { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-pdf.svg) }
  191 +.bigicon-application-ogg { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-ogg.svg) }
  192 +.bigicon-video, .icon-video-mpeg { background-image: url(Tango/scalable/mimetypes/video-x-generic.svg) }
  193 +.bigicon-application-vnd-oasis-opendocument-text { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-vnd.oasis.opendocument.text.svg) }
  194 +.bigicon-application-vnd-oasis-opendocument-spreadsheet { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-vnd.oasis.opendocument.spreadsheet.svg) }
  195 +.bigicon-application-vnd-oasis-opendocument-presentation { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-vnd.oasis.opendocument.presentation.svg) }
  196 +.bigicon-welcome-page { background-image: url(mod/scalable/mimetypes/welcome-page.svg) }
  197 +.bigicon-blocks { background-image: url(mod/scalable/mimetypes/blocks.svg) }
  198 +.bigicon-header-footer { background-image: url(mod/scalable/mimetypes/header-footer.svg) }
  199 +.bigicon-appearance { background-image: url(Tango/scalable/apps/preferences-desktop-wallpaper.svg) }
  200 +.bigicon-media-pause { background-image: url(Tango/scalable/actions/media-playback-pause.svg) }
  201 +.bigicon-media-play { background-image: url(Tango/scalable/actions/media-playback-start.svg) }
  202 +.bigicon-media-prev { background-image: url(Tango/scalable/actions/media-skip-backward.svg) }
  203 +.bigicon-media-next { background-image: url(Tango/scalable/actions/media-skip-forward.svg) }
  204 +.bigicon-lock { background-image: url(Tango/scalable/actions/lock.svg) }
  205 +.bigicon-chat { background-image: url(Tango/scalable/apps/internet-group-chat.svg); background-repeat: no-repeat }
  206 +.bigicon-reply { background-image: url(Tango/scalable/actions/mail-reply-sender.svg) }
  207 +.bigicon-newforum { background-image: url(Tango/scalable/apps/internet-group-chat.svg) }
  208 +.bigicon-forum { background-image: url(Tango/scalable/apps/system-users.svg) }
  209 +.bigicon-gallery { background-image: url(Tango/scalable/mimetypes/image-x-generic.svg) }
  210 +.bigicon-newgallery { background-image: url(Tango/scalable/mimetypes/image-x-generic.svg) }
  211 +.bigicon-locale { background-image: url(Tango/scalable/apps/preferences-desktop-locale.svg) }
  212 +.bigicon-user-removed { background-image: url(Tango/scalable/actions/gtk-cancel.svg) }
  213 +.bigicon-user-unknown { background-image: url(Tango/scalable/status/dialog-error.svg) }
  214 +.bigicon-alert { background-image: url(Tango/scalable/status/dialog-warning.svg) }
  215 +.bigicon-clone { background-image: url(Tango/scalable/actions/edit-copy.svg) }
  216 +.bigicon-activate-user { background-image: url(Tango/scalable/emblems/emblem-system.svg) }
  217 +.bigicon-deactivate-user { background-image: url(Tango/scalable/emblems/emblem-unreadable.svg) }
  218 +.bigicon-clock { background-image: url(Tango/scalable/actions/appointment.svg) }
  219 +
119 /******************LARGE ICONS********************/ 220 /******************LARGE ICONS********************/
120 .image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) } 221 .image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) }
121 .image-gallery-item .gallery { background-image: url(mod/96x96/mimetypes/image-x-generic.png) } 222 .image-gallery-item .gallery { background-image: url(mod/96x96/mimetypes/image-x-generic.png) }
public/images/icons-app/image-loading-bigicon.png 0 → 100644

3.24 KB

public/javascripts/media-panel.js
1 -var file_id = 1;  
2 -  
3 -jQuery('.view-all-media').on('click', '.pagination a', function(event) {  
4 - jQuery.ajax({  
5 - url: this.href,  
6 - beforeSend: function(){jQuery('.view-all-media').addClass('fetching')},  
7 - complete: function() {jQuery('.view-all-media').removeClass('fetching')},  
8 - dataType: 'script' 1 +(function($) {
  2 + "use strict";
  3 +
  4 + var file_id = 1;
  5 +
  6 + $('.view-all-media').on('click', '.pagination a', function(event) {
  7 + $.ajax({
  8 + url: this.href,
  9 + beforeSend: function(){$('.view-all-media').addClass('fetching')},
  10 + complete: function() {$('.view-all-media').removeClass('fetching')},
  11 + dataType: 'script'
  12 + });
  13 + return false;
9 }); 14 });
10 - return false;  
11 -});  
12 -  
13 -jQuery('#file').fileupload({  
14 - add: function(e, data){  
15 - data.files[0].id = file_id;  
16 - file_id++;  
17 - data.context = jQuery(tmpl("template-upload", data.files[0]));  
18 - jQuery('#media-upload-form').append(data.context);  
19 - data.submit();  
20 - },  
21 - progress: function (e, data) {  
22 - if (jQuery('#hide-uploads').data('bootstraped') == false) {  
23 - jQuery('#hide-uploads').show();  
24 - jQuery('#hide-uploads').data('bootstraped', true);  
25 - }  
26 - if (data.context) {  
27 - progress = parseInt(data.loaded / data.total * 100, 10);  
28 - data.context.find('.bar').css('width', progress + '%');  
29 - data.context.find('.percentage').text(progress + '%');  
30 - }  
31 - },  
32 - fail: function(e, data){  
33 - var file_id = '#file-'+data.files[0].id;  
34 - jQuery(file_id).find('.progress .bar').addClass('error');  
35 - jQuery(file_id).append("<div class='error-message'>" + data.jqXHR.responseText + "</div>")  
36 - }  
37 -});  
38 -  
39 -jQuery('#hide-uploads').click(function(){  
40 - jQuery('#hide-uploads').hide();  
41 - jQuery('#show-uploads').show();  
42 - jQuery('.upload').slideUp();  
43 - return false;  
44 -});  
45 -  
46 -jQuery('#show-uploads').click(function(){  
47 - jQuery('#hide-uploads').show();  
48 - jQuery('#show-uploads').hide();  
49 - jQuery('.upload').slideDown();  
50 - return false;  
51 -});  
52 -  
53 -function loadPublishedMedia() {  
54 - var parent_id = jQuery('#published-media #parent_id').val();  
55 - var q = jQuery('#published-media #q').val();  
56 - var url = jQuery('#published-media').data('url');  
57 -  
58 - jQuery('#published-media .items').addClass('fetching');  
59 - jQuery.ajax({  
60 - url: url,  
61 - data: {'parent_id': parent_id, 'q': q},  
62 - dataType: 'html',  
63 - success: function(response) {  
64 - jQuery("#published-media .items").html(response);  
65 - jQuery('#published-media .items').removeClass('fetching');  
66 - updateViewAllLinks(); 15 +
  16 +
  17 + $('#file').fileupload({
  18 + add: function(e, data){
  19 + data.files[0].id = file_id;
  20 + file_id++;
  21 + data.context = $(tmpl("template-upload", data.files[0]));
  22 + $('#media-upload-form').append(data.context);
  23 + data.submit();
  24 + },
  25 + progress: function (e, data) {
  26 + if ($('#hide-uploads').data('bootstraped') == false) {
  27 + $('#hide-uploads').show();
  28 + $('#hide-uploads').data('bootstraped', true);
  29 + }
  30 + if (data.context) {
  31 + var progress = parseInt(data.loaded / data.total * 100, 10);
  32 + data.context.find('.bar').css('width', progress + '%');
  33 + data.context.find('.percentage').text(progress + '%');
  34 + }
67 }, 35 },
68 - error: function(response, textStatus, xhr) {  
69 - console.log(response);  
70 - console.log(textStatus); 36 + fail: function(e, data){
  37 + var file_id = '#file-'+data.files[0].id;
  38 + $(file_id).find('.progress .bar').addClass('error');
  39 + $(file_id).append("<div class='error-message'>" + data.jqXHR.responseText + "</div>")
71 } 40 }
72 }); 41 });
73 -}  
74 -  
75 -function updateViewAllLinks() {  
76 - var parent_id = jQuery('#published-media #parent_id').val();  
77 - var q = jQuery('#published-media #q').val();  
78 - jQuery('#published-media .view-all').each(function(){  
79 - var key = jQuery(this).data('key');  
80 - var params = {parent_id: parent_id, q: q, key: key}  
81 - var href = jQuery(this).attr('href');  
82 - href = href.replace(/\?.*/, '?'+jQuery.param(params));  
83 - jQuery(this).attr('href', href); 42 +
  43 +
  44 + $('#hide-uploads').click(function(){
  45 + $('#hide-uploads').hide();
  46 + $('#show-uploads').show();
  47 + $('.upload').slideUp();
  48 + return false;
  49 + });
  50 +
  51 +
  52 + $('#show-uploads').click(function(){
  53 + $('#hide-uploads').show();
  54 + $('#show-uploads').hide();
  55 + $('.upload').slideDown();
  56 + return false;
84 }); 57 });
85 -}  
86 -  
87 -jQuery('#published-media #parent_id').change(function(){ loadPublishedMedia() });  
88 -  
89 -jQuery("#published-media #q").typeWatch({  
90 - callback: function (value) { loadPublishedMedia() },  
91 - wait: 750,  
92 - highlight: true,  
93 - captureLength: 2  
94 -});  
95 -  
96 -jQuery("#published-media #q").bind('notext', function(){ loadPublishedMedia() });  
97 -  
98 -jQuery("#new-folder-dialog").submit(function( event ) {  
99 - var name = jQuery('#new_folder').val();  
100 - var parent_id = jQuery("#new-folder-dialog #parent_id").val();  
101 - jQuery.ajax({  
102 - url: this.action,  
103 - type: 'POST',  
104 - data: {  
105 - 'parent_id': parent_id,  
106 - 'article': {'name': name, 'published': true},  
107 - 'type': jQuery('input[name=folder_type]:checked').val() },  
108 - dataType: 'json',  
109 - beforeSend: function(){jQuery("#new-folder-dialog").addClass('fetching')},  
110 - success: function(response) {  
111 - var option_selected = "<option value='"+ response.id +"' selected='selected'>"+ response.full_name +"</options>"  
112 - var option = "<option value='"+ response.id +"'>"+ response.full_name +"</options>"  
113 - jQuery('#media-upload-form #parent_id').append(option_selected);  
114 - jQuery('#published-media #parent_id').append(option);  
115 - jQuery('#new_folder').val('');  
116 - },  
117 - error: function(response, textStatus, xhr) {  
118 - console.log(response);  
119 - console.log(textStatus);  
120 - },  
121 - complete: function(response){  
122 - jQuery("#new-folder-dialog").removeClass('fetching');  
123 - jQuery("#new-folder-dialog").dialog('close');  
124 - } 58 +
  59 +
  60 + function loadPublishedMedia() {
  61 + var parent_id = $('#published-media #parent_id').val();
  62 + var q = $('#published-media #q').val();
  63 + var url = $('#published-media').data('url');
  64 +
  65 + $('#published-media .items').addClass('fetching');
  66 + $.ajax({
  67 + url: url,
  68 + data: {'parent_id': parent_id, 'q': q},
  69 + dataType: 'html',
  70 + success: function(response) {
  71 + $("#published-media .items").html(response);
  72 + $('#published-media .items').removeClass('fetching');
  73 + updateViewAllLinks();
  74 + },
  75 + error: function(response, textStatus, xhr) {
  76 + console.log(response);
  77 + console.log(textStatus);
  78 + }
  79 + });
  80 + }
  81 + // make it global for usage in media_upload.js.erb
  82 + window.loadPublishedMedia = loadPublishedMedia;
  83 +
  84 +
  85 + function updateViewAllLinks() {
  86 + var parent_id = $('#published-media #parent_id').val();
  87 + var q = $('#published-media #q').val();
  88 + $('#published-media .view-all').each(function(){
  89 + var key = $(this).data('key');
  90 + var params = {parent_id: parent_id, q: q, key: key}
  91 + var href = $(this).attr('href');
  92 + href = href.replace(/\?.*/, '?'+$.param(params));
  93 + $(this).attr('href', href);
  94 + });
  95 + }
  96 +
  97 +
  98 + $('#published-media #parent_id').change(function(){
  99 + loadPublishedMedia()
  100 + });
  101 +
  102 +
  103 + // Using a immediate function to make timer variable only visible for the keyup event
  104 + (function() {
  105 + var timer = null;
  106 +
  107 + $("#published-media #q").keyup(function() {
  108 + if(this.value.length > 2) {
  109 + timer = setTimeout(loadPublishedMedia, 750);
  110 + }
  111 + }).keydown(function() {
  112 + clearTimeout(timer);
  113 + });
  114 + }) ();
  115 +
  116 +
  117 + $("#published-media #q").bind('notext', function(){
  118 + loadPublishedMedia()
  119 + });
  120 +
  121 +
  122 + $("#new-folder-dialog").submit(function( event ) {
  123 + var name = $('#new_folder').val();
  124 + var parent_id = $("#new-folder-dialog #parent_id").val();
  125 + $.ajax({
  126 + url: this.action,
  127 + type: 'POST',
  128 + data: {
  129 + 'parent_id': parent_id,
  130 + 'article': {'name': name, 'published': true},
  131 + 'type': $('input[name=folder_type]:checked').val() },
  132 + dataType: 'json',
  133 + beforeSend: function(){$("#new-folder-dialog").addClass('fetching')},
  134 + success: function(response) {
  135 + var option_selected = "<option value='"+ response.id +"' selected='selected'>"+ response.full_name +"</options>"
  136 + var option = "<option value='"+ response.id +"'>"+ response.full_name +"</options>"
  137 + $('#media-upload-form #parent_id').append(option_selected);
  138 + $('#published-media #parent_id').append(option);
  139 + $('#new_folder').val('');
  140 + },
  141 + error: function(response, textStatus, xhr) {
  142 + console.log(response);
  143 + console.log(textStatus);
  144 + },
  145 + complete: function(response){
  146 + $("#new-folder-dialog").removeClass('fetching');
  147 + $("#new-folder-dialog").dialog('close');
  148 + }
  149 + });
  150 + return false;
  151 + });
  152 +
  153 + $('.icon-vertical-toggle').click(function(){
  154 + $('#content').toggleClass('show-media-panel');
  155 + return false;
125 }); 156 });
126 - return false;  
127 -});  
128 -  
129 -jQuery('.text-editor-sidebar .header .icon-vertical-toggle').click(function(){  
130 - jQuery('#content').toggleClass('show-media-panel');  
131 - return false;  
132 -});  
133 -  
134 -jQuery('#new-folder-button').click(function(){  
135 - jQuery('#new-folder-dialog').dialog({modal: true});  
136 - return false;  
137 -}); 157 +
  158 +
  159 + $('#new-folder-button').click(function(){
  160 + $('#new-folder-dialog').dialog({modal: true});
  161 + return false;
  162 + });
  163 +
  164 +}) (jQuery);
public/stylesheets/application.scss
@@ -1561,6 +1561,32 @@ div.article-body p img { @@ -1561,6 +1561,32 @@ div.article-body p img {
1561 #content .blog-post .read-more a { 1561 #content .blog-post .read-more a {
1562 margin: 0 10px; 1562 margin: 0 10px;
1563 } 1563 }
  1564 +
  1565 +#content #article .blog-posts .blog-post .article-compact-abstract{
  1566 + position: relative;
  1567 + float:left;
  1568 + margin-left: 10px;
  1569 + width: 100%;
  1570 + word-wrap: break-word;
  1571 +}
  1572 +
  1573 +#content #article .blog-posts .blog-post .article-compact-image{
  1574 + position:relative;
  1575 + float:left;
  1576 + width: 27%;
  1577 + display: table-cell;
  1578 + vertical-align: middle;
  1579 + text-align: center;
  1580 + margin-top: 15px;
  1581 +}
  1582 +
  1583 +#content #article .blog-posts .blog-post .article-compact-abstract-with-image{
  1584 + position: relative;
  1585 + float:left;
  1586 + margin-left: 10px;
  1587 + width: 70%;
  1588 + word-wrap: break-word;
  1589 +}
1564 /* NOT PUBLISHED BLOG POSTS */ 1590 /* NOT PUBLISHED BLOG POSTS */
1565 1591
1566 .blog-post.not-published { 1592 .blog-post.not-published {
@@ -3832,6 +3858,11 @@ table.cms-articles .icon:hover { @@ -3832,6 +3858,11 @@ table.cms-articles .icon:hover {
3832 3858
3833 /* Folders */ 3859 /* Folders */
3834 3860
  3861 +.article-body ul.folder-content {
  3862 + list-style-type: none;
  3863 + padding: 0;
  3864 +}
  3865 +
3835 .folder-content .folder-item img { 3866 .folder-content .folder-item img {
3836 vertical-align: middle; 3867 vertical-align: middle;
3837 position: relative; 3868 position: relative;
@@ -3897,6 +3928,62 @@ table.cms-articles .icon:hover { @@ -3897,6 +3928,62 @@ table.cms-articles .icon:hover {
3897 right: auto; 3928 right: auto;
3898 left: auto; 3929 left: auto;
3899 } 3930 }
  3931 +
  3932 +/**************Folder Style**********************/
  3933 +
  3934 +.list-item{
  3935 + font-family: arial;
  3936 + color: #172738;
  3937 +}
  3938 +
  3939 +div.folder-description {
  3940 + padding-bottom: 15px;
  3941 +}
  3942 +
  3943 +.list-item h2{
  3944 + border-bottom:1px solid #ccc;
  3945 + margin:0px;
  3946 +}
  3947 +
  3948 +.item-info{
  3949 + border-top: 1px solid #ccc;
  3950 + line-height: 25px;
  3951 + padding:25px 20px;
  3952 +}
  3953 +
  3954 +.item-info a{
  3955 + text-decoration: none !important;
  3956 + font-size: 16px;
  3957 + font-weight: bold;
  3958 +}
  3959 +
  3960 +.item-icon a {
  3961 + float: left;
  3962 + width: 50px;
  3963 + height: 50px;
  3964 + background-repeat: no-repeat;
  3965 + background-position: center center;
  3966 +}
  3967 +
  3968 +span.item-type {
  3969 + font-size: 12px;
  3970 +}
  3971 +
  3972 +.item-description{
  3973 + display: block;
  3974 + position:relative;
  3975 + margin-left: 15%;
  3976 + padding-left: 10px;
  3977 +}
  3978 +
  3979 +.item-date{
  3980 + display:block;
  3981 + position:relative;
  3982 + font-size: 12px;
  3983 + margin-left: 15%;
  3984 + padding-left: 10px;
  3985 +}
  3986 +
3900 /************* enterprise homepage style *****************/ 3987 /************* enterprise homepage style *****************/
3901 3988
3902 div.event-info { 3989 div.event-info {
test/functional/admin_panel_controller_test.rb
@@ -130,6 +130,19 @@ class AdminPanelControllerTest &lt; ActionController::TestCase @@ -130,6 +130,19 @@ class AdminPanelControllerTest &lt; ActionController::TestCase
130 assert_equal "This <strong>is</strong> my new environment", Environment.default.message_for_disabled_enterprise 130 assert_equal "This <strong>is</strong> my new environment", Environment.default.message_for_disabled_enterprise
131 end 131 end
132 132
  133 + should 'save site article date format option' do
  134 + post :site_info, :environment => { :date_format => "numbers_with_year" }
  135 + assert_redirected_to :action => 'index'
  136 +
  137 + assert_equal "numbers_with_year", Environment.default.date_format
  138 + end
  139 +
  140 + should 'dont save site article date format option when a invalid option is passed' do
  141 + post :site_info, :environment => { :date_format => "invalid_format" }
  142 +
  143 + assert_not_equal "invalid_format", Environment.default.date_format
  144 + end
  145 +
133 should 'set portal community' do 146 should 'set portal community' do
134 e = Environment.default 147 e = Environment.default
135 @controller.stubs(:environment).returns(e) 148 @controller.stubs(:environment).returns(e)
test/functional/application_controller_test.rb
@@ -484,7 +484,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -484,7 +484,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
484 should 'change postgresql schema' do 484 should 'change postgresql schema' do
485 uses_host 'schema1.com' 485 uses_host 'schema1.com'
486 Noosfero::MultiTenancy.expects(:on?).returns(true) 486 Noosfero::MultiTenancy.expects(:on?).returns(true)
487 - Noosfero::MultiTenancy.expects(:mapping).returns({ 'schema1.com' => 'schema1' }) 487 + Noosfero::MultiTenancy.expects(:mapping).returns({ 'schema1.com' => 'schema1' }).at_least_once
488 exception = assert_raise(ActiveRecord::StatementInvalid) { get :index } 488 exception = assert_raise(ActiveRecord::StatementInvalid) { get :index }
489 assert_match /SET search_path TO schema1/, exception.message 489 assert_match /SET search_path TO schema1/, exception.message
490 end 490 end
test/functional/content_viewer_controller_test.rb
@@ -262,7 +262,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -262,7 +262,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
262 262
263 get :view_page, :profile => 'test_profile', :page => [ 'my-intranet' ] 263 get :view_page, :profile => 'test_profile', :page => [ 'my-intranet' ]
264 264
265 - assert_template "profile/_private_profile" 265 + assert_template "shared/access_denied"
266 end 266 end
267 267
268 should 'not give access to private articles if logged in but not member' do 268 should 'not give access to private articles if logged in but not member' do
@@ -1527,12 +1527,12 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1527,12 +1527,12 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1527 should 'use context method in extra toolbar actions on article from plugins' do 1527 should 'use context method in extra toolbar actions on article from plugins' do
1528 class Plugin1 < Noosfero::Plugin 1528 class Plugin1 < Noosfero::Plugin
1529 def article_extra_toolbar_buttons(article) 1529 def article_extra_toolbar_buttons(article)
1530 - if current_person.public? 1530 + if profile.public?
1531 {:title => 'some_title', :icon => 'some_icon', :url => '/someurl'} 1531 {:title => 'some_title', :icon => 'some_icon', :url => '/someurl'}
1532 else 1532 else
1533 {:title => 'another_title', :icon => 'another_icon', :url => '/anotherurl'} 1533 {:title => 'another_title', :icon => 'another_icon', :url => '/anotherurl'}
1534 end 1534 end
1535 - end 1535 + end
1536 end 1536 end
1537 Noosfero::Plugin.stubs(:all).returns([Plugin1.name]) 1537 Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
1538 1538
@@ -1547,4 +1547,31 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1547,4 +1547,31 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1547 assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :href => "/anotherurl" }} 1547 assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :href => "/anotherurl" }}
1548 end 1548 end
1549 1549
  1550 + should 'show lead,image and title in compact blog visualization' do
  1551 + community = Community.create(:name => 'test-community')
  1552 + community.add_member(@profile)
  1553 + community.save!
  1554 +
  1555 + blog = community.articles.find_by_name("Blog")
  1556 + blog.visualization_format = 'compact'
  1557 + blog.save!
  1558 +
  1559 + article = TinyMceArticle.create(:name => 'Article to be shared with images',
  1560 + :body => 'This article should be shared with all social networks',
  1561 + :profile => @profile,
  1562 + :published => false,
  1563 + :abstract => "teste teste teste",
  1564 + :show_to_followers => true,
  1565 + :image_builder => { :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')} )
  1566 + article.parent = blog
  1567 + article.save!
  1568 +
  1569 + login_as(@profile.identifier)
  1570 +
  1571 +
  1572 + get :view_page, :profile => community.identifier, "page" => 'blog'
  1573 +
  1574 + assert_tag :tag => 'div', :attributes => { :class => 'article-compact-image' }
  1575 + assert_tag :tag => 'div', :attributes => { :class => 'article-compact-abstract-with-image' }
  1576 + end
1550 end 1577 end
test/functional/friends_controller_test.rb
@@ -46,7 +46,7 @@ class FriendsControllerTest &lt; ActionController::TestCase @@ -46,7 +46,7 @@ class FriendsControllerTest &lt; ActionController::TestCase
46 46
47 should 'display find people button' do 47 should 'display find people button' do
48 get :index, :profile => 'testuser' 48 get :index, :profile => 'testuser'
49 - assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/assets/people' } 49 + assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/search/assets?asset=people' }
50 end 50 end
51 51
52 should 'not display invite friends button if any plugin tells not to' do 52 should 'not display invite friends button if any plugin tells not to' do
@@ -76,25 +76,25 @@ class FriendsControllerTest &lt; ActionController::TestCase @@ -76,25 +76,25 @@ class FriendsControllerTest &lt; ActionController::TestCase
76 end 76 end
77 77
78 should 'display people suggestions' do 78 should 'display people suggestions' do
79 - profile.profile_suggestions.create(:suggestion => friend) 79 + profile.suggested_profiles.create(:suggestion => friend)
80 get :suggest, :profile => 'testuser' 80 get :suggest, :profile => 'testuser'
81 assert_tag :tag => 'a', :content => "+ #{friend.name}", :attributes => { :href => "/profile/#{friend.identifier}/add" } 81 assert_tag :tag => 'a', :content => "+ #{friend.name}", :attributes => { :href => "/profile/#{friend.identifier}/add" }
82 end 82 end
83 83
84 should 'display button to add friend suggestion' do 84 should 'display button to add friend suggestion' do
85 - profile.profile_suggestions.create(:suggestion => friend) 85 + profile.suggested_profiles.create(:suggestion => friend)
86 get :suggest, :profile => 'testuser' 86 get :suggest, :profile => 'testuser'
87 assert_tag :tag => 'a', :attributes => { :href => "/profile/#{friend.identifier}/add" } 87 assert_tag :tag => 'a', :attributes => { :href => "/profile/#{friend.identifier}/add" }
88 end 88 end
89 89
90 should 'display button to remove people suggestion' do 90 should 'display button to remove people suggestion' do
91 - profile.profile_suggestions.create(:suggestion => friend) 91 + profile.suggested_profiles.create(:suggestion => friend)
92 get :suggest, :profile => 'testuser' 92 get :suggest, :profile => 'testuser'
93 assert_tag :tag => 'a', :attributes => { :href => /\/myprofile\/testuser\/friends\/remove_suggestion\/#{friend.identifier}/ } 93 assert_tag :tag => 'a', :attributes => { :href => /\/myprofile\/testuser\/friends\/remove_suggestion\/#{friend.identifier}/ }
94 end 94 end
95 95
96 should 'remove suggestion of friend' do 96 should 'remove suggestion of friend' do
97 - suggestion = profile.profile_suggestions.create(:suggestion => friend) 97 + suggestion = profile.suggested_profiles.create(:suggestion => friend)
98 post :remove_suggestion, :profile => 'testuser', :id => friend.identifier 98 post :remove_suggestion, :profile => 'testuser', :id => friend.identifier
99 99
100 assert_response :success 100 assert_response :success
test/functional/memberships_controller_test.rb
@@ -331,35 +331,35 @@ class MembershipsControllerTest &lt; ActionController::TestCase @@ -331,35 +331,35 @@ class MembershipsControllerTest &lt; ActionController::TestCase
331 331
332 should 'display list suggestions button' do 332 should 'display list suggestions button' do
333 community = fast_create(Community) 333 community = fast_create(Community)
334 - profile.profile_suggestions.create(:suggestion => community) 334 + profile.suggested_profiles.create(:suggestion => community)
335 get :index, :profile => 'testuser' 335 get :index, :profile => 'testuser'
336 assert_tag :tag => 'a', :content => 'See some suggestions of communities...', :attributes => { :href => "/myprofile/testuser/memberships/suggest" } 336 assert_tag :tag => 'a', :content => 'See some suggestions of communities...', :attributes => { :href => "/myprofile/testuser/memberships/suggest" }
337 end 337 end
338 338
339 should 'display communities suggestions' do 339 should 'display communities suggestions' do
340 community = fast_create(Community) 340 community = fast_create(Community)
341 - profile.profile_suggestions.create(:suggestion => community) 341 + profile.suggested_profiles.create(:suggestion => community)
342 get :suggest, :profile => 'testuser' 342 get :suggest, :profile => 'testuser'
343 assert_tag :tag => 'a', :content => "+ #{community.name}", :attributes => { :href => "/profile/#{community.identifier}/join" } 343 assert_tag :tag => 'a', :content => "+ #{community.name}", :attributes => { :href => "/profile/#{community.identifier}/join" }
344 end 344 end
345 345
346 should 'display button to join on community suggestion' do 346 should 'display button to join on community suggestion' do
347 community = fast_create(Community) 347 community = fast_create(Community)
348 - profile.profile_suggestions.create(:suggestion => community) 348 + profile.suggested_profiles.create(:suggestion => community)
349 get :suggest, :profile => 'testuser' 349 get :suggest, :profile => 'testuser'
350 assert_tag :tag => 'a', :attributes => { :href => "/profile/#{community.identifier}/join" } 350 assert_tag :tag => 'a', :attributes => { :href => "/profile/#{community.identifier}/join" }
351 end 351 end
352 352
353 should 'display button to remove community suggestion' do 353 should 'display button to remove community suggestion' do
354 community = fast_create(Community) 354 community = fast_create(Community)
355 - profile.profile_suggestions.create(:suggestion => community) 355 + profile.suggested_profiles.create(:suggestion => community)
356 get :suggest, :profile => 'testuser' 356 get :suggest, :profile => 'testuser'
357 assert_tag :tag => 'a', :attributes => { :href => /\/myprofile\/testuser\/memberships\/remove_suggestion\/#{community.identifier}/ } 357 assert_tag :tag => 'a', :attributes => { :href => /\/myprofile\/testuser\/memberships\/remove_suggestion\/#{community.identifier}/ }
358 end 358 end
359 359
360 should 'remove suggestion of community' do 360 should 'remove suggestion of community' do
361 community = fast_create(Community) 361 community = fast_create(Community)
362 - suggestion = profile.profile_suggestions.create(:suggestion => community) 362 + suggestion = profile.suggested_profiles.create(:suggestion => community)
363 post :remove_suggestion, :profile => 'testuser', :id => community.identifier 363 post :remove_suggestion, :profile => 'testuser', :id => community.identifier
364 364
365 assert_response :success 365 assert_response :success
test/functional/organizations_controller_test.rb
@@ -86,22 +86,22 @@ class OrganizationsControllerTest &lt; ActionController::TestCase @@ -86,22 +86,22 @@ class OrganizationsControllerTest &lt; ActionController::TestCase
86 86
87 should 'activate organization profile' do 87 should 'activate organization profile' do
88 organization = fast_create(Organization, :visible => false, :environment_id => environment.id) 88 organization = fast_create(Organization, :visible => false, :environment_id => environment.id)
89 - assert organization.disabled? 89 + assert !organization.visible?
90 90
91 get :activate, {:id => organization.id} 91 get :activate, {:id => organization.id}
92 organization.reload 92 organization.reload
93 93
94 - assert organization.enabled? 94 + assert organization.visible
95 end 95 end
96 96
97 should 'deactivate organization profile' do 97 should 'deactivate organization profile' do
98 organization = fast_create(Organization, :visible => true, :environment_id => environment.id) 98 organization = fast_create(Organization, :visible => true, :environment_id => environment.id)
99 - assert organization.enabled? 99 + assert organization.visible
100 100
101 get :deactivate, {:id => organization.id} 101 get :deactivate, {:id => organization.id}
102 organization.reload 102 organization.reload
103 103
104 - assert organization.disabled? 104 + assert !organization.visible
105 end 105 end
106 106
107 should 'destroy organization profile' do 107 should 'destroy organization profile' do
test/functional/profile_controller_test.rb
@@ -508,11 +508,15 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -508,11 +508,15 @@ class ProfileControllerTest &lt; ActionController::TestCase
508 end 508 end
509 509
510 should 'show description of person' do 510 should 'show description of person' do
  511 + environment = Environment.default
  512 + environment.custom_person_fields = {:description => { :active => true, :required => false, :signup => false }}
  513 + environment.save!
  514 + environment.reload
511 login_as(@profile.identifier) 515 login_as(@profile.identifier)
512 - @profile.description = 'Person\'s description'  
513 - @profile.save 516 + @profile.description = 'Person description'
  517 + @profile.save!
514 get :index, :profile => @profile.identifier 518 get :index, :profile => @profile.identifier
515 - assert_tag :tag => 'div', :attributes => { :class => 'public-profile-description' }, :content => /Person\'s description/ 519 + assert_tag :tag => 'div', :attributes => { :class => 'public-profile-description' }, :content => /Person description/
516 end 520 end
517 521
518 should 'not show description of orgarnization if not filled' do 522 should 'not show description of orgarnization if not filled' do
test/functional/tasks_controller_test.rb
@@ -520,4 +520,120 @@ class TasksControllerTest &lt; ActionController::TestCase @@ -520,4 +520,120 @@ class TasksControllerTest &lt; ActionController::TestCase
520 assert !json_response['success'] 520 assert !json_response['success']
521 end 521 end
522 522
  523 + should 'list tasks for user with only view_tasks permission' do
  524 + community = fast_create(Community)
  525 + @controller.stubs(:profile).returns(community)
  526 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  527 + login_as person.user.login
  528 + get :index
  529 + assert_response :success
  530 + assert assigns(:view_only)
  531 + end
  532 +
  533 + should 'forbid user with only view_tasks permission to close a task' do
  534 + community = fast_create(Community)
  535 + @controller.stubs(:profile).returns(community)
  536 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  537 + login_as person.user.login
  538 + post :close
  539 + assert_response 403
  540 + end
  541 +
  542 + should 'hide tasks actions when user has only view_tasks permission' do
  543 + community = fast_create(Community)
  544 + @controller.stubs(:profile).returns(community)
  545 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  546 + login_as person.user.login
  547 +
  548 + Task.create!(:requestor => person, :target => community)
  549 + get :index
  550 +
  551 + assert_select '.task-actions', 0
  552 + end
  553 +
  554 + should 'display tasks actions when user has perform_task permission' do
  555 + community = fast_create(Community)
  556 + @controller.stubs(:profile).returns(community)
  557 + person = create_user_with_permission('taskperformer', 'perform_task', community)
  558 + login_as person.user.login
  559 +
  560 + Task.create!(:requestor => person, :target => community)
  561 + get :index
  562 +
  563 + assert_select '.task-actions', 2
  564 + end
  565 +
  566 + should 'hide decision selector when user has only view_tasks permission' do
  567 + community = fast_create(Community)
  568 + @controller.stubs(:profile).returns(community)
  569 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  570 + login_as person.user.login
  571 +
  572 + Task.create!(:requestor => person, :target => community)
  573 + get :index
  574 +
  575 + assert_select '#up-set-all-tasks-to', 0
  576 + assert_select '#down-set-all-tasks-to', 0
  577 + end
  578 +
  579 + should 'display decision selector when user has perform_task permission' do
  580 + community = fast_create(Community)
  581 + @controller.stubs(:profile).returns(community)
  582 + person = create_user_with_permission('taskperformer', 'perform_task', community)
  583 + login_as person.user.login
  584 +
  585 + Task.create!(:requestor => person, :target => community)
  586 + get :index
  587 +
  588 + assert_select '#up-set-all-tasks-to'
  589 + assert_select '#down-set-all-tasks-to'
  590 + end
  591 +
  592 + should 'hide decision buttons when user has only view_tasks permission' do
  593 + community = fast_create(Community)
  594 + @controller.stubs(:profile).returns(community)
  595 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  596 + login_as person.user.login
  597 +
  598 + task = Task.create!(:requestor => person, :target => community)
  599 + get :index
  600 +
  601 + assert_select "#decision-finish-#{task.id}", 0
  602 + assert_select "#decision-cancel-#{task.id}", 0
  603 + assert_select "#decision-skip-#{task.id}", 0
  604 + end
  605 +
  606 + should 'display decision buttons when user has perform_task permission' do
  607 + community = fast_create(Community)
  608 + @controller.stubs(:profile).returns(community)
  609 + person = create_user_with_permission('taskperformer', 'perform_task', community)
  610 + login_as person.user.login
  611 +
  612 + task = Task.create!(:requestor => person, :target => community)
  613 + get :index
  614 +
  615 + assert_select "#decision-finish-#{task.id}"
  616 + assert_select "#decision-cancel-#{task.id}"
  617 + assert_select "#decision-skip-#{task.id}"
  618 + end
  619 +
  620 + should 'hide responsive selection when user has only view_tasks permission' do
  621 + community = fast_create(Community)
  622 + @controller.stubs(:profile).returns(community)
  623 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  624 + login_as person.user.login
  625 +
  626 + task = Task.create!(:requestor => person, :target => community, :responsible => person)
  627 + get :index
  628 +
  629 + assert_select ".task_responsible select", 0
  630 + assert_select ".task_responsible .value"
  631 + end
  632 +
  633 + should 'store the person who closes a task' do
  634 + t = profile.tasks.build; t.save!
  635 + post :close, :tasks => {t.id => {:decision => 'finish', :task => {}}}
  636 + assert_equal profile, t.reload.closed_by
  637 + end
  638 +
523 end 639 end
test/integration/routing_test.rb
@@ -135,7 +135,7 @@ class RoutingTest &lt; ActionController::IntegrationTest @@ -135,7 +135,7 @@ class RoutingTest &lt; ActionController::IntegrationTest
135 end 135 end
136 136
137 def test_assets_routing 137 def test_assets_routing
138 - assert_routing('/assets/my-asset/a/b/c', :controller => 'search', :action => 'assets', :asset => 'my-asset', :category_path => 'a/b/c') 138 + assert_routing('/search/assets/a/b/c', :controller => 'search', :action => 'assets', :category_path => 'a/b/c')
139 end 139 end
140 140
141 def test_content_view_with_dot 141 def test_content_view_with_dot
test/test_helper.rb
@@ -262,10 +262,6 @@ module NoosferoTestHelper @@ -262,10 +262,6 @@ module NoosferoTestHelper
262 arg 262 arg
263 end 263 end
264 264
265 - def show_date(date)  
266 - date.to_s  
267 - end  
268 -  
269 def strip_tags(html) 265 def strip_tags(html)
270 html.gsub(/<[^>]+>/, '') 266 html.gsub(/<[^>]+>/, '')
271 end 267 end