Commit a0b7561861d71d533d3b8eacfce2eff5f7c52db9

Authored by Leandro Santos
2 parents 5fa41591 c5df21ab

merging with master

Showing 404 changed files with 23824 additions and 10101 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 404 files displayed.

.gitlab-ci.yml 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +before_script:
  2 + - mkdir -p tmp/pids log
  3 + - bundle check || bundle install
  4 + - script/noosfero-plugins disableall
  5 + - bundle exec rake makemo &>/dev/null
  6 +# database
  7 + - cp config/database.yml.gitlab-ci config/database.yml
  8 + - createdb gitlab_ci_test || true
  9 + - bundle exec rake db:schema:load &>/dev/null
  10 + - bundle exec rake db:migrate &>/dev/null
  11 +
  12 +units:
  13 + script: bundle exec rake test:units
  14 +functionals:
  15 + script: bundle exec rake test:functionals
  16 +integration:
  17 + script: bundle exec rake test:integration
  18 +cucumber:
  19 + script: bundle exec rake cucumber
  20 +selenium:
  21 + script: bundle exec rake selenium
  22 +plugins:
  23 + script: bundle exec rake test:noosfero_plugins
  24 +
... ...
.travis.yml 0 → 100644
... ... @@ -0,0 +1,50 @@
  1 +language: ruby
  2 +rvm:
  3 +# for 2.2 support we need to upgrade the pg gem
  4 + - 2.1.6
  5 +cache: bundler
  6 +
  7 +sudo: false
  8 +addons:
  9 + apt:
  10 + packages:
  11 + - po4a
  12 + - iso-codes
  13 + - tango-icon-theme
  14 + - pidgin-data
  15 + # for gem extensions
  16 + - libmagickwand-dev
  17 + - libpq-dev
  18 + - libreadline-dev
  19 + - libsqlite3-dev
  20 + - libxslt1-dev
  21 +
  22 +before_install:
  23 +# FIXME: workaround while https://github.com/travis-ci/travis-ci/issues/4210 is open
  24 + - rm config/initializers/default_icon_theme.rb
  25 +# selenium support
  26 + - export DISPLAY=:99.0
  27 + - sh -e /etc/init.d/xvfb start
  28 +
  29 +before_script:
  30 + - mkdir -p tmp/pids log
  31 + - bundle check || bundle install
  32 + - script/noosfero-plugins disableall
  33 + - bundle exec rake makemo &>/dev/null
  34 +# database
  35 + - cp config/database.yml.travis config/database.yml
  36 + - psql -c 'create database myapp_test;' -U postgres
  37 + - bundle exec rake db:schema:load &>/dev/null
  38 + - bundle exec rake db:migrate &>/dev/null
  39 +
  40 +env:
  41 + - TASK=test:units
  42 + - TASK=test:functionals
  43 + - TASK=test:integration
  44 + - TASK=cucumber
  45 + - TASK=selenium
  46 + - TASK=test:noosfero_plugins
  47 +
  48 +script:
  49 + - bundle exec rake $TASK
  50 +
... ...
Gemfile
1 1 source "https://rubygems.org"
2   -gem 'rails', '~> 3.2.21'
  2 +gem 'rails', '~> 3.2.22'
3 3 gem 'minitest', '~> 3.2.0'
4 4 gem 'fast_gettext', '~> 0.6.8'
5 5 gem 'acts-as-taggable-on', '~> 3.4.2'
... ... @@ -18,7 +18,7 @@ gem 'exception_notification', '~> 4.0.1'
18 18 gem 'gettext', '~> 2.2.1', :require => false
19 19 gem 'locale', '~> 2.0.5'
20 20 gem 'whenever', :require => false
21   -gem 'eita-jrails', '>= 0.9.5', :require => 'jrails'
  21 +gem 'eita-jrails', '~> 0.9.5', require: 'jrails'
22 22  
23 23 # asset pipeline
24 24 gem 'uglifier', '>= 1.0.3'
... ... @@ -32,6 +32,7 @@ group :test do
32 32 gem 'rspec', '~> 2.14.0'
33 33 gem 'rspec-rails', '~> 2.14.1'
34 34 gem 'mocha', '~> 1.1.0', :require => false
  35 + gem 'test-unit' if RUBY_VERSION >= '2.2.0'
35 36 end
36 37  
37 38 group :cucumber do
... ...
INSTALL.https.md
... ... @@ -11,8 +11,8 @@ as below:
11 11  
12 12 # mkdir /etc/noosfero/ssl
13 13 # cd /etc/noosfero/ssl
14   - # openssl genrsa 1024 > noosfero.key
15   - # openssl req -new -x509 -nodes -sha1 -days $[10*365] -key noosfero.key > noosfero.cert
  14 + # openssl genrsa 2048 > noosfero.key
  15 + # openssl req -new -x509 -sha256 -nodes -days $[10*365] -key noosfero.key > noosfero.cert
16 16 # cat noosfero.key noosfero.cert > noosfero.pem
17 17  
18 18 ## Web server configuration
... ...
INSTALL.md
... ... @@ -74,7 +74,7 @@ downloading from git
74 74  
75 75 Here we are cloning the noosfero repository from git. Note: you will need to install git before.
76 76  
77   - $ git clone git://gitorious.org/noosfero/noosfero.git current
  77 + $ git clone https://gitlab.com/noosfero/noosfero.git current
78 78 $ cd current
79 79 $ git checkout -b stable origin/stable
80 80  
... ...
app/controllers/admin/admin_panel_controller.rb
... ... @@ -71,22 +71,4 @@ class AdminPanelController < AdminController
71 71 end
72 72 end
73 73 end
74   -
75   - def manage_organizations_status
76   - scope = environment.organizations
77   - @filter = params[:filter] || 'any'
78   - @title = "Organization profiles"
79   - @title = @title+" - "+@filter if @filter != 'any'
80   -
81   - if @filter == 'enabled'
82   - scope = scope.visible
83   - elsif @filter == 'disabled'
84   - scope = scope.disabled
85   - end
86   -
87   - scope = scope.order('name ASC')
88   -
89   - @q = params[:q]
90   - @collection = find_by_contents(:organizations, environment, scope, @q, {:per_page => 10, :page => params[:npage]})[:results]
91   - end
92 74 end
... ...
app/controllers/admin/organizations_controller.rb 0 → 100644
... ... @@ -0,0 +1,66 @@
  1 +class OrganizationsController < AdminController
  2 +
  3 + protect 'manage_environment_organizations', :environment
  4 +
  5 + def index
  6 + @filter = params[:filter] || 'any'
  7 + @title = _('Organization profiles')
  8 + @type = params[:type] || "any"
  9 + @types_filter = [[_('All'), 'any'], [_('Community'), 'Community'], [_('Enterprise'), 'Enterprise']]
  10 + @types_filter = @types_filter | @plugins.dispatch(:organization_types_filter_options)
  11 +
  12 + scope = @plugins.dispatch_first(:filter_manage_organization_scope, @type)
  13 + if scope.blank?
  14 + scope = environment.organizations
  15 + scope = scope.where(:type => @type) if @type != 'any'
  16 + end
  17 +
  18 + if @filter == 'enabled'
  19 + scope = scope.visible
  20 + elsif @filter == 'disabled'
  21 + scope = scope.disabled
  22 + end
  23 +
  24 + scope = scope.order('name ASC')
  25 +
  26 + @q = params[:q]
  27 + @collection = find_by_contents(:organizations, environment, scope, @q, {:per_page => per_page, :page => params[:npage]})[:results]
  28 + end
  29 +
  30 + def activate
  31 + organization = environment.organizations.find(params[:id])
  32 + if organization.enable
  33 + render :text => (_('%s enabled') % organization.name).to_json
  34 + else
  35 + render :text => (_('%s could not be enabled') % organization.name).to_json
  36 + end
  37 + end
  38 +
  39 + def deactivate
  40 + organization = environment.organizations.find(params[:id])
  41 + if organization.disable
  42 + render :text => (_('%s disabled') % organization.name).to_json
  43 + else
  44 + render :text => (_('%s could not be disable') % organization.name).to_json
  45 + end
  46 + end
  47 +
  48 + def destroy
  49 + if request.post?
  50 + organization = environment.organizations.find(params[:id])
  51 + if organization && organization.destroy
  52 + render :text => (_('%s removed') % organization.name).to_json
  53 + else
  54 + render :text => (_('%s could not be removed') % organization.name).to_json
  55 + end
  56 + else
  57 + render :nothing => true
  58 + end
  59 + end
  60 +
  61 + private
  62 +
  63 + def per_page
  64 + 10
  65 + end
  66 +end
... ...
app/controllers/application_controller.rb
... ... @@ -72,8 +72,8 @@ class ApplicationController &lt; ActionController::Base
72 72 FastGettext.available_locales = environment.available_locales
73 73 FastGettext.default_locale = environment.default_locale
74 74 FastGettext.locale = (params[:lang] || session[:lang] || environment.default_locale || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en')
75   - I18n.locale = FastGettext.locale
76   - I18n.default_locale = FastGettext.default_locale
  75 + I18n.locale = FastGettext.locale.to_s.gsub '_', '-'
  76 + I18n.default_locale = FastGettext.default_locale.to_s.gsub '_', '-'
77 77 if params[:lang]
78 78 session[:lang] = params[:lang]
79 79 end
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -6,7 +6,7 @@ class CmsController &lt; MyProfileController
6 6  
7 7 def search_tags
8 8 arg = params[:term].downcase
9   - result = ActsAsTaggableOn::Tag.find(:all, :conditions => ['LOWER(name) LIKE ?', "%#{arg}%"])
  9 + result = ActsAsTaggableOn::Tag.where('name ILIKE ?', "%#{arg}%").limit(10)
10 10 render :text => prepare_to_token_input_by_label(result).to_json, :content_type => 'application/json'
11 11 end
12 12  
... ... @@ -101,6 +101,11 @@ class CmsController &lt; MyProfileController
101 101 record_coming
102 102 if request.post?
103 103 @article.image = nil if params[:remove_image] == 'true'
  104 + if @article.image.present? && params[:article][:image_builder] &&
  105 + params[:article][:image_builder][:label]
  106 + @article.image.label = params[:article][:image_builder][:label]
  107 + @article.image.save!
  108 + end
104 109 @article.last_changed_by = user
105 110 if @article.update_attributes(params[:article])
106 111 if !continue
... ... @@ -112,6 +117,11 @@ class CmsController &lt; MyProfileController
112 117 end
113 118 end
114 119 end
  120 +
  121 + unless @article.kind_of?(RssFeed)
  122 + @escaped_body = CGI::escapeHTML(@article.body || '')
  123 + @escaped_abstract = CGI::escapeHTML(@article.abstract || '')
  124 + end
115 125 end
116 126  
117 127 def new
... ... @@ -144,7 +154,13 @@ class CmsController &lt; MyProfileController
144 154 article_data = environment.enabled?('articles_dont_accept_comments_by_default') ? { :accept_comments => false } : {}
145 155 article_data.merge!(params[:article]) if params[:article]
146 156 article_data.merge!(:profile => profile) if profile
147   - @article = klass.new(article_data)
  157 +
  158 + @article = if params[:clone]
  159 + current_article = profile.articles.find(params[:id])
  160 + current_article.copy_without_save
  161 + else
  162 + klass.new(article_data)
  163 + end
148 164  
149 165 parent = check_parent(params[:parent_id])
150 166 if parent
... ...
app/controllers/my_profile/friends_controller.rb
1 1 class FriendsController < MyProfileController
2   -
  2 +
3 3 protect 'manage_friends', :profile
4   -
  4 +
5 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 7 if is_cache_expired?(profile.manage_friends_cache_key(params))
8 8 @friends = profile.friends.paginate(:per_page => per_page, :page => params[:npage])
9 9 end
... ... @@ -18,7 +18,7 @@ class FriendsController &lt; MyProfileController
18 18 end
19 19  
20 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 22 end
23 23  
24 24 def remove_suggestion
... ... @@ -26,13 +26,13 @@ class FriendsController &lt; MyProfileController
26 26 redirect_to :action => 'suggest' unless @person
27 27 if @person && request.post?
28 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 30 render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions, :per_page => params[:per_page] || per_page }
31 31 end
32 32 end
33 33  
34 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 36 if @suggestion
37 37 @tags = @suggestion.tag_connections
38 38 @profiles = @suggestion.profile_connections
... ...
app/controllers/my_profile/manage_products_controller.rb
... ... @@ -35,7 +35,7 @@ class ManageProductsController &lt; ApplicationController
35 35 end
36 36  
37 37 def categories_for_selection
38   - @category = Category.find(params[:category_id]) if params[:category_id]
  38 + @category = environment.categories.find_by_id params[:category_id]
39 39 @object_name = params[:object_name]
40 40 if @category
41 41 @categories = @category.children
... ... @@ -95,6 +95,20 @@ class ManageProductsController &lt; ApplicationController
95 95 end
96 96 end
97 97  
  98 + def show_category_tree
  99 + @category = environment.categories.find params[:category_id]
  100 + render :partial => 'selected_category_tree'
  101 + end
  102 +
  103 + def search_categories
  104 + @term = params[:term].downcase
  105 + conditions = ['LOWER(name) LIKE ? OR LOWER(name) LIKE ?', "#{@term}%", "% #{@term}%"]
  106 + @categories = ProductCategory.all :conditions => conditions, :limit => 10
  107 + render :json => (@categories.map do |category|
  108 + {:label => category.name, :value => category.id}
  109 + end)
  110 + end
  111 +
98 112 def add_input
99 113 @product = @profile.products.find(params[:id])
100 114 @input = @product.inputs.build
... ...
app/controllers/my_profile/maps_controller.rb
... ... @@ -16,6 +16,7 @@ class MapsController &lt; MyProfileController
16 16  
17 17 Profile.transaction do
18 18 if profile.update_attributes!(params[:profile_data])
  19 + BlockSweeper.expire_blocks profile.blocks.select{ |b| b.class == LocationBlock }
19 20 session[:notice] = _('Address was updated successfully!')
20 21 redirect_to :action => 'edit_location'
21 22 end
... ...
app/controllers/my_profile/memberships_controller.rb
... ... @@ -40,7 +40,7 @@ class MembershipsController &lt; MyProfileController
40 40 end
41 41  
42 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 44 end
45 45  
46 46 def remove_suggestion
... ... @@ -49,13 +49,13 @@ class MembershipsController &lt; MyProfileController
49 49 redirect_to :action => 'suggest' unless @community
50 50 if @community && request.post?
51 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 53 render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :communities_suggestions, :per_page => custom_per_page}
54 54 end
55 55 end
56 56  
57 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 59 if @suggestion
60 60 @tags = @suggestion.tag_connections
61 61 @profiles = @suggestion.profile_connections
... ...
app/controllers/my_profile/tasks_controller.rb
1 1 class TasksController < MyProfileController
2 2  
3   - protect 'perform_task', :profile
4   -
  3 + protect [:perform_task, :view_tasks], :profile, :only => [:index]
  4 + protect :perform_task, :profile, :except => [:index]
  5 +
5 6 def index
6   - @filter_type = params[:filter_type] = params[:filter_type].blank? ? nil : params[:filter_type]
7   - @filter_text = params[:filter_text].blank? ? nil : params[:filter_text]
  7 + @filter_type = params[:filter_type].presence
  8 + @filter_text = params[:filter_text].presence
  9 + @filter_responsible = params[:filter_responsible]
8 10 @task_types = Task.pending_types_for(profile)
9   - @tasks = Task.pending_all(profile,params).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page])
  11 +
  12 + @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc')
  13 + @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present?
  14 + @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page])
  15 +
10 16 @failed = params ? params[:failed] : {}
  17 +
  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)
11 21 end
12 22  
13 23 def processed
14 24 @tasks = Task.to(profile).without_spam.closed.sort_by(&:created_at)
15 25 end
16 26  
  27 + def change_responsible
  28 + task = profile.tasks.find(params[:task_id])
  29 +
  30 + if task.responsible.present? && task.responsible.id != params[:old_responsible_id].to_i
  31 + return render :json => {:notice => _('Task already assigned!'), :success => false, :current_responsible => task.responsible.id}
  32 + end
  33 +
  34 + responsible = profile.members.find(params[:responsible_id]) if params[:responsible_id].present?
  35 + task.responsible = responsible
  36 + task.save!
  37 + render :json => {:notice => _('Task responsible successfully updated!'), :success => true, :new_responsible => {:id => responsible.present? ? responsible.id : nil}}
  38 + end
  39 +
17 40 VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ]
18 41  
19 42 def close
... ... @@ -26,7 +49,7 @@ class TasksController &lt; MyProfileController
26 49 task = profile.find_in_all_tasks(id)
27 50 begin
28 51 task.update_attributes(value[:task])
29   - task.send(decision)
  52 + task.send(decision, current_person)
30 53 rescue Exception => ex
31 54 message = "#{task.title} (#{task.requestor ? task.requestor.name : task.author_name})"
32 55 failed[ex.message] ? failed[ex.message] << message : failed[ex.message] = [message]
... ...
app/controllers/public/chat_controller.rb
... ... @@ -2,6 +2,7 @@ class ChatController &lt; PublicController
2 2  
3 3 before_filter :login_required
4 4 before_filter :check_environment_feature
  5 + before_filter :can_send_message, :only => :register_message
5 6  
6 7 def start_session
7 8 login = user.jid
... ... @@ -54,6 +55,16 @@ class ChatController &lt; PublicController
54 55 end
55 56 end
56 57  
  58 + def avatars
  59 + profiles = environment.profiles.where(:identifier => params[:profiles])
  60 + avatar_map = profiles.inject({}) do |result, profile|
  61 + result[profile.identifier] = profile_icon(profile, :minor)
  62 + result
  63 + end
  64 +
  65 + render_json avatar_map
  66 + end
  67 +
57 68 def update_presence_status
58 69 if request.xhr?
59 70 current_user.update_attributes({:chat_status_at => DateTime.now}.merge(params[:status] || {}))
... ... @@ -62,11 +73,17 @@ class ChatController &lt; PublicController
62 73 end
63 74  
64 75 def save_message
65   - to = environment.profiles.find_by_identifier(params[:to])
66   - body = params[:body]
67   -
68   - ChatMessage.create!(:to => to, :from => user, :body => body)
69   - render :text => 'ok'
  76 + if request.post?
  77 + to = environment.profiles.where(:identifier => params[:to]).first
  78 + body = params[:body]
  79 +
  80 + begin
  81 + ChatMessage.create!(:to => to, :from => user, :body => body)
  82 + return render_json({:status => 0})
  83 + rescue Exception => exception
  84 + return render_json({:status => 3, :message => exception.to_s, :backtrace => exception.backtrace})
  85 + end
  86 + end
70 87 end
71 88  
72 89 def recent_messages
... ... @@ -90,8 +107,9 @@ class ChatController &lt; PublicController
90 107 end
91 108  
92 109 def recent_conversations
93   - conversations_order = ActiveRecord::Base.connection.execute("select profiles.identifier from profiles inner join (select distinct r.id as id, MAX(r.created_at) as created_at from (select from_id, to_id, created_at, (case when from_id=#{user.id} then to_id else from_id end) as id from chat_messages where from_id=#{user.id} or to_id=#{user.id}) as r group by id order by created_at desc, id) as t on profiles.id=t.id order by t.created_at desc").entries.map {|e| e['identifier']}
94   - render :json => {:order => conversations_order.reverse, :domain => environment.default_hostname.gsub('.','-')}.to_json
  110 + profiles = Profile.find_by_sql("select profiles.* from profiles inner join (select distinct r.id as id, MAX(r.created_at) as created_at from (select from_id, to_id, created_at, (case when from_id=#{user.id} then to_id else from_id end) as id from chat_messages where from_id=#{user.id} or to_id=#{user.id}) as r group by id order by created_at desc, id) as t on profiles.id=t.id order by t.created_at desc")
  111 + jids = profiles.map(&:jid).reverse
  112 + render :json => jids.to_json
95 113 end
96 114  
97 115 #TODO Ideally this is done through roster table on ejabberd.
... ... @@ -108,4 +126,14 @@ class ChatController &lt; PublicController
108 126 end
109 127 end
110 128  
  129 + def can_send_message
  130 + return render_json({:status => 1, :message => 'Missing parameters!'}) if params[:from].nil? || params[:to].nil? || params[:message].nil?
  131 + return render_json({:status => 2, :message => 'You can not send message as another user!'}) if params[:from] != user.jid
  132 + # TODO Maybe register the jid in a table someday to avoid this below
  133 + return render_json({:status => 3, :messsage => 'You can not send messages to strangers!'}) if user.friends.where(:identifier => params[:to].split('@').first).blank?
  134 + end
  135 +
  136 + def render_json(result)
  137 + render :text => result.to_json
  138 + end
111 139 end
... ...
app/controllers/public/content_viewer_controller.rb
... ... @@ -11,6 +11,7 @@ class ContentViewerController &lt; ApplicationController
11 11 path = get_path(params[:page], params[:format])
12 12  
13 13 @version = params[:version].to_i
  14 + @npage = params[:npage] || '1'
14 15  
15 16 if path.blank?
16 17 @page = profile.home_page
... ... @@ -127,7 +128,7 @@ class ContentViewerController &lt; ApplicationController
127 128 end
128 129  
129 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 132 render_access_denied
132 133 else #!profile.public?
133 134 private_profile_partial_parameters
... ...
app/helpers/application_helper.rb
... ... @@ -871,7 +871,7 @@ module ApplicationHelper
871 871 field_html += capture(&block)
872 872 end
873 873  
874   - if controller.action_name == 'signup' || controller.action_name == 'new_community' || (controller.controller_name == "enterprise_registration" && controller.action_name == 'index')
  874 + if controller.action_name == 'signup' || controller.action_name == 'new_community' || (controller.controller_name == "enterprise_registration" && controller.action_name == 'index') || (controller.controller_name == 'home' && controller.action_name == 'index' && user.nil?)
875 875 if profile.signup_fields.include?(name)
876 876 result = field_html
877 877 end
... ... @@ -931,6 +931,19 @@ module ApplicationHelper
931 931 article_helper.cms_label_for_edit
932 932 end
933 933  
  934 + def label_for_clone_article(article)
  935 + translated_types = {
  936 + Folder => _('Folder'),
  937 + Blog => _('Blog'),
  938 + Event => _('Event'),
  939 + Forum => _('Forum')
  940 + }
  941 +
  942 + translated_type = translated_types[article.class] || _('Article')
  943 +
  944 + _('Clone %s') % translated_type
  945 + end
  946 +
934 947 def add_rss_feed_to_head(title, url)
935 948 content_for :feeds do
936 949 tag(:link, :rel => 'alternate', :type => 'application/rss+xml', :title => title, :href => url_for(url))
... ... @@ -1172,7 +1185,7 @@ module ApplicationHelper
1172 1185 pending_tasks_count = link_to(count.to_s, user.tasks_url, :id => 'pending-tasks-count', :title => _("Manage your pending tasks"))
1173 1186 end
1174 1187  
1175   - (_("<span class='welcome'>Welcome,</span> %s") % link_to("<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>", user.public_profile_url, :id => "homepage-link", :title => _('Go to your homepage'))) +
  1188 + (_("<span class='welcome'>Welcome,</span> %s") % link_to("<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>", user.url, :id => "homepage-link", :title => _('Go to your homepage'))) +
1176 1189 render_environment_features(:usermenu) +
1177 1190 admin_link +
1178 1191 manage_enterprises +
... ... @@ -1202,35 +1215,6 @@ module ApplicationHelper
1202 1215 list.sort.inject(Hash.new(0)){|h,i| h[i] += 1; h }.collect{ |x, n| [n, connector, x].join(" ") }.sort
1203 1216 end
1204 1217  
1205   - #FIXME Use time_ago_in_words instead of this method if you're using Rails 2.2+
1206   - def time_ago_as_sentence(from_time, include_seconds = false)
1207   - to_time = Time.now
1208   - from_time = Time.parse(from_time.to_s)
1209   - from_time = from_time.to_time if from_time.respond_to?(:to_time)
1210   - to_time = to_time.to_time if to_time.respond_to?(:to_time)
1211   - distance_in_minutes = (((to_time - from_time).abs)/60).round
1212   - distance_in_seconds = ((to_time - from_time).abs).round
1213   - case distance_in_minutes
1214   - when 0..1
1215   - return (distance_in_minutes == 0) ? _('less than a minute') : _('1 minute') unless include_seconds
1216   - case distance_in_seconds
1217   - when 0..4 then _('less than 5 seconds')
1218   - when 5..9 then _('less than 10 seconds')
1219   - when 10..19 then _('less than 20 seconds')
1220   - when 20..39 then _('half a minute')
1221   - when 40..59 then _('less than a minute')
1222   - else _('1 minute')
1223   - end
1224   -
1225   - when 2..44 then _('%{distance} minutes ago') % { :distance => distance_in_minutes }
1226   - when 45..89 then _('about 1 hour ago')
1227   - when 90..1439 then _('about %{distance} hours ago') % { :distance => (distance_in_minutes.to_f / 60.0).round }
1228   - when 1440..2879 then _('1 day ago')
1229   - when 2880..10079 then _('%{distance} days ago') % { :distance => (distance_in_minutes / 1440).round }
1230   - else show_time(from_time)
1231   - end
1232   - end
1233   -
1234 1218 def comment_balloon(options = {}, &block)
1235 1219 wrapper = content_tag(:div, capture(&block), :class => 'comment-balloon-content')
1236 1220 (1..8).to_a.reverse.each { |i| wrapper = content_tag(:div, wrapper, :class => "comment-wrapper-#{i}") }
... ... @@ -1249,7 +1233,7 @@ module ApplicationHelper
1249 1233  
1250 1234 def task_information(task)
1251 1235 values = {}
1252   - values.merge!({:requestor => link_to(task.requestor.name, task.requestor.public_profile_url)}) if task.requestor
  1236 + values.merge!({:requestor => link_to(task.requestor.name, task.requestor.url)}) if task.requestor
1253 1237 values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject
1254 1238 values.merge!({:linked_subject => link_to(content_tag('span', task.linked_subject[:text], :class => 'task_target'), task.linked_subject[:url])}) if task.linked_subject
1255 1239 values.merge!(task.information[:variables]) if task.information[:variables]
... ...
app/helpers/blog_helper.rb
... ... @@ -22,7 +22,9 @@ module BlogHelper
22 22 :param_name => 'npage',
23 23 :previous_label => _('&laquo; Newer posts'),
24 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 28 }) if articles.present? && conf[:paginate]
27 29 content = []
28 30 artic_len = articles.length
... ... @@ -44,7 +46,7 @@ module BlogHelper
44 46 end
45 47  
46 48 def display_post(article, format = 'full')
47   - no_comments = (format == 'full') ? false : true
  49 + no_comments = (format == 'full' || format == 'compact' ) ? false : true
48 50 title = article_title(article, :no_comments => no_comments)
49 51 method = "display_#{format.split('+')[0]}_format"
50 52 html = send(method, FilePresenter.for(article)).html_safe
... ... @@ -55,8 +57,12 @@ module BlogHelper
55 57 else
56 58 '<div class="post-pic" style="background-image:url('+img+')"></div>'
57 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 66 end
61 67  
62 68 def display_full_format(article)
... ...
app/helpers/boxes_helper.rb
... ... @@ -122,7 +122,7 @@ module BoxesHelper
122 122 end
123 123  
124 124 def wrap_main_content(content)
125   - (1..8).to_a.reverse.inject(content) { |acc,n| content_tag('div', acc, :id => 'main-content-wrapper-' + n.to_s) }
  125 + content_tag('div', content, :class => 'main-content')
126 126 end
127 127  
128 128 def extract_block_content(content)
... ...
app/helpers/chat_helper.rb
... ... @@ -9,12 +9,12 @@ module ChatHelper
9 9 avatar = profile_image(user, :portrait, :class => 'avatar')
10 10 content_tag('span',
11 11 link_to(avatar + content_tag('span', user.name) + ui_icon('ui-icon-triangle-1-s'),
12   - '#',
  12 + '',
13 13 :onclick => 'toggleMenu(this); return false',
14 14 :class => icon_class + ' simplemenu-trigger'
15 15 ) +
16 16 content_tag('ul',
17   - links.map{|link| content_tag('li', link_to(link[1], '#', :class => link[0], :id => link[2], 'data-jid' => user.jid), :class => 'simplemenu-item') }.join("\n"),
  17 + links.map{|link| content_tag('li', link_to(link[1], '', :class => link[0], :id => link[2], 'data-jid' => user.jid), :class => 'simplemenu-item') }.join("\n"),
18 18 :style => 'display: none; z-index: 100',
19 19 :class => 'simplemenu-submenu'
20 20 ),
... ...
app/helpers/comment_helper.rb
1 1 module CommentHelper
  2 + include DatesHelper
2 3  
3 4 def article_title(article, args = {})
4 5 title = article.title
... ... @@ -15,7 +16,7 @@ module CommentHelper
15 16 content_tag('span', show_date(article.published_at), :class => 'date') +
16 17 content_tag('span', [_(", by %s") % link_to(article.author_name, article.author_url)], :class => 'author') +
17 18 content_tag('span', comments, :class => 'comments'),
18   - :class => 'created-at'
  19 + :class => 'publishing-info'
19 20 )
20 21 end
21 22 title
... ...
app/helpers/content_viewer_helper.rb
... ... @@ -2,6 +2,7 @@ module ContentViewerHelper
2 2  
3 3 include BlogHelper
4 4 include ForumHelper
  5 + include DatesHelper
5 6  
6 7 def display_number_of_comments(n)
7 8 base_str = "<span class='comment-count hide'>#{n}</span>"
... ... @@ -24,16 +25,35 @@ module ContentViewerHelper
24 25 unless args[:no_comments] || !article.accept_comments
25 26 comments = (" - %s") % link_to_comments(article)
26 27 end
  28 + date_format = show_with_right_format_date article
27 29 title << content_tag('span',
28   - content_tag('span', show_date(article.published_at), :class => 'date') +
  30 + date_format +
29 31 content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') +
30 32 content_tag('span', comments, :class => 'comments'),
31   - :class => 'created-at'
  33 + :class => 'publishing-info'
32 34 )
33 35 end
34 36 title
35 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 57 def link_to_comments(article, args = {})
38 58 return '' unless article.accept_comments?
39 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 2  
3 3 module DatesHelper
4 4  
  5 + include ActionView::Helpers::DateHelper
5 6 def months
6 7 I18n.t('date.month_names')
7 8 end
... ... @@ -15,10 +16,12 @@ module DatesHelper
15 16 end
16 17  
17 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 20 if date && use_numbers
20 21 date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}')
21 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 25 elsif date
23 26 date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}')
24 27 date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year }
... ...
app/helpers/events_helper.rb
1 1 module EventsHelper
2 2  
  3 + include DatesHelper
3 4 def list_events(date, events)
4 5 title = _('Events for %s') % show_date_month(date)
5 6 content_tag('h2', title) +
... ...
app/helpers/folder_helper.rb
1   -require 'short_filename'
2   -
3 1 module FolderHelper
4 2  
5   - include ShortFilename
6 3 include ArticleHelper
7 4  
8 5 def list_contents(configure={})
... ... @@ -10,8 +7,8 @@ module FolderHelper
10 7 configure[:list_type] ||= :folder
11 8 if !configure[:contents].blank?
12 9 configure[:contents] = configure[:contents].paginate(
13   - :order => "updated_at DESC",
14   - :per_page => 10,
  10 + :order => "name ASC",
  11 + :per_page => 30,
15 12 :page => params[:npage]
16 13 )
17 14  
... ... @@ -25,49 +22,32 @@ module FolderHelper
25 22 articles.select {|article| article.display_to?(user)}
26 23 end
27 24  
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]
  25 + def display_content_icon(content_item)
  26 + content = FilePresenter.for content_item
33 27 content_link = if content.image?
34   - link_to('&nbsp;' * (level * 4) +
35   - image_tag(icon_for_article(content)) + short_filename(content.name),
  28 + link_to(
  29 + image_tag(icon_for_article(content, :bigicon)),
36 30 content.url.merge(:view => true)
37 31 )
38 32 else
39   - link_to('&nbsp;' * (level * 4) +
40   - short_filename(content.name),
41   - content.url.merge(:view => true), :class => icon_for_article(content)
  33 + link_to('',
  34 + content.url.merge(:view => true),
  35 + :class => icon_for_article(content, :bigicon)
42 36 )
43 37 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 38 end
59 39  
60   - def icon_for_article(article)
  40 + def icon_for_article(article, size = 'icon')
61 41 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
  42 + if article.respond_to?(:sized_icon)
  43 + article.sized_icon(size)
67 44 else
68   - klasses = 'icon ' + [icon].flatten.map{|name| 'icon-'+name}.join(' ')
  45 + icon = article.respond_to?(:icon_name) ?
  46 + article.icon_name :
  47 + article.class.icon_name(article)
  48 + klasses = "#{size} " + [icon].flatten.map{|name| "#{size}-"+name}.join(' ')
69 49 if article.kind_of?(UploadedFile) || article.kind_of?(FilePresenter)
70   - klasses += ' icon-upload-file'
  50 + klasses += " #{size}-upload-file"
71 51 end
72 52 klasses
73 53 end
... ...
app/helpers/forum_helper.rb
1 1 module ForumHelper
  2 + include ActionView::Helpers::DateHelper
2 3  
3 4 def cms_label_for_new_children
4 5 _('New discussion topic')
... ... @@ -42,9 +43,9 @@ module ForumHelper
42 43 def last_topic_update(article)
43 44 info = article.info_from_last_update
44 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 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 49 end
49 50 end
50 51  
... ...
app/helpers/manage_products_helper.rb
... ... @@ -75,9 +75,12 @@ module ManageProductsHelper
75 75 end
76 76  
77 77 def categories_container(categories_selection_html, hierarchy_html = '')
78   - hidden_field_tag('selected_category_id') +
79   - content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') +
80   - content_tag('div', categories_selection_html, :id => 'categories_container_wrapper')
  78 + content_tag 'div',
  79 + render('categories_autocomplete') +
  80 + hidden_field_tag('selected_category_id') +
  81 + content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') +
  82 + content_tag('div', categories_selection_html, :id => 'categories_container_wrapper'),
  83 + :id => 'categories-container'
81 84 end
82 85  
83 86 def select_for_categories(categories, level = 0)
... ...
app/helpers/profile_editor_helper.rb
... ... @@ -141,8 +141,9 @@ module ProfileEditorHelper
141 141 )
142 142 end
143 143  
144   - def control_panel_button(title, icon, url)
145   - link_to title, url, :class => 'control-panel-%s' % icon
  144 + def control_panel_button(title, icon, url, html_options = {})
  145 + html_options ||= {}
  146 + link_to title, url, html_options.merge(:class => 'control-panel-%s' % icon)
146 147 end
147 148  
148 149 def unchangeable_privacy_field(profile)
... ...
app/helpers/search_helper.rb
... ... @@ -106,6 +106,10 @@ module SearchHelper
106 106 end
107 107 end
108 108  
  109 + def city_with_state_for_profile(p)
  110 + city_with_state(p.region) || [p.city, p.state].compact.reject(&:blank?).join(', ')
  111 + end
  112 +
109 113 def display_selector(asset, display, float = 'right')
110 114 display = nil if display.blank?
111 115 display ||= asset_class(asset).default_search_display
... ...
app/helpers/users_helper.rb
... ... @@ -14,7 +14,7 @@ module UsersHelper
14 14 select_field = select_tag(:filter, options, :onchange => onchange)
15 15 content_tag('div',
16 16 content_tag('strong', _('Filter')) + ': ' + select_field,
17   - :class => "environment-users-customize-search"
  17 + :class => "environment-profiles-customize-search"
18 18 )
19 19 end
20 20  
... ...
app/models/add_friend.rb
... ... @@ -54,7 +54,7 @@ class AddFriend &lt; Task
54 54 end
55 55  
56 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 58 suggestion.disable if suggestion
59 59 end
60 60 end
... ...
app/models/article.rb
... ... @@ -28,7 +28,7 @@ class Article &lt; ActiveRecord::Base
28 28 def initialize(*params)
29 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 32 profile = params.first[:profile]
33 33 self.published = false unless profile.public?
34 34 end
... ... @@ -96,6 +96,8 @@ class Article &lt; ActiveRecord::Base
96 96 belongs_to :translation_of, :class_name => 'Article', :foreign_key => :translation_of_id
97 97 before_destroy :rotate_translations
98 98  
  99 + acts_as_voteable
  100 +
99 101 before_create do |article|
100 102 article.published_at ||= Time.now
101 103 if article.reference_article && !article.parent
... ... @@ -129,7 +131,7 @@ class Article &lt; ActiveRecord::Base
129 131  
130 132 scope :by_range, lambda { |range| {
131 133 :conditions => [
132   - 'published_at BETWEEN :start_date AND :end_date', { :start_date => range.first, :end_date => range.last }
  134 + 'articles.published_at BETWEEN :start_date AND :end_date', { :start_date => range.first, :end_date => range.last }
133 135 ]
134 136 }}
135 137  
... ... @@ -577,25 +579,24 @@ class Article &lt; ActiveRecord::Base
577 579 profile.visible? && profile.public? && published?
578 580 end
579 581  
580   -
581   - def copy(options = {})
  582 + def copy_without_save(options = {})
582 583 attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) }
583 584 attrs.merge!(options)
584 585 object = self.class.new
585 586 attrs.each do |key, value|
586 587 object.send(key.to_s+'=', value)
587 588 end
  589 + object
  590 + end
  591 +
  592 + def copy(options = {})
  593 + object = copy_without_save(options)
588 594 object.save
589 595 object
590 596 end
591 597  
592 598 def copy!(options = {})
593   - attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) }
594   - attrs.merge!(options)
595   - object = self.class.new
596   - attrs.each do |key, value|
597   - object.send(key.to_s+'=', value)
598   - end
  599 + object = copy_without_save(options)
599 600 object.save!
600 601 object
601 602 end
... ... @@ -723,8 +724,9 @@ class Article &lt; ActiveRecord::Base
723 724 paragraphs.empty? ? '' : paragraphs.first.to_html
724 725 end
725 726  
726   - def lead
727   - abstract.blank? ? first_paragraph.html_safe : abstract.html_safe
  727 + def lead(length = nil)
  728 + content = abstract.blank? ? first_paragraph.html_safe : abstract.html_safe
  729 + length.present? ? content.truncate(length) : content
728 730 end
729 731  
730 732 def short_lead
... ...
app/models/block.rb
... ... @@ -2,7 +2,7 @@ class Block &lt; ActiveRecord::Base
2 2  
3 3 attr_accessible :title, :display, :limit, :box_id, :posts_per_page,
4 4 :visualization_format, :language, :display_user,
5   - :box, :edit_modes, :move_modes
  5 + :box, :edit_modes, :move_modes, :mirror
6 6  
7 7 # to be able to generate HTML
8 8 include ActionView::Helpers::UrlHelper
... ... @@ -15,11 +15,23 @@ class Block &lt; ActiveRecord::Base
15 15  
16 16 acts_as_list :scope => :box
17 17 belongs_to :box
  18 + belongs_to :mirror_block, :class_name => "Block"
  19 + has_many :observers, :class_name => "Block", :foreign_key => "mirror_block_id"
18 20  
19 21 acts_as_having_settings
20 22  
21 23 scope :enabled, :conditions => { :enabled => true }
22 24  
  25 + after_save do |block|
  26 + if block.owner.kind_of?(Profile) && block.owner.is_template? && block.mirror?
  27 + block.observers.each do |observer|
  28 + observer.copy_from(block)
  29 + observer.title = block.title
  30 + observer.save
  31 + end
  32 + end
  33 + end
  34 +
23 35 def embedable?
24 36 false
25 37 end
... ... @@ -269,6 +281,10 @@ class Block &lt; ActiveRecord::Base
269 281 self.position = block.position
270 282 end
271 283  
  284 + def add_observer(block)
  285 + self.observers << block
  286 + end
  287 +
272 288 private
273 289  
274 290 def home_page_path
... ...
app/models/blog.rb
... ... @@ -76,9 +76,12 @@ class Blog &lt; Folder
76 76 end
77 77  
78 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 86 alias :display_posts_in_current_language? :display_posts_in_current_language
84 87  
... ...
app/models/chat_message.rb
... ... @@ -4,4 +4,5 @@ class ChatMessage &lt; ActiveRecord::Base
4 4 belongs_to :to, :class_name => 'Profile'
5 5 belongs_to :from, :class_name => 'Profile'
6 6  
  7 + validates_presence_of :from, :to
7 8 end
... ...
app/models/comment.rb
... ... @@ -37,6 +37,8 @@ class Comment &lt; ActiveRecord::Base
37 37  
38 38 xss_terminate :only => [ :body, :title, :name ], :on => 'validation'
39 39  
  40 + acts_as_voteable
  41 +
40 42 def comment_root
41 43 (reply_of && reply_of.comment_root) || self
42 44 end
... ...
app/models/environment.rb
... ... @@ -3,7 +3,17 @@
3 3 # domains.
4 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 18 has_many :users
9 19  
... ... @@ -14,6 +24,12 @@ class Environment &lt; ActiveRecord::Base
14 24  
15 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 33 def self.verify_filename(filename)
18 34 filename += '.txt' if File.extname(filename) =~ IDENTIFY_SCRIPTS
19 35 filename
... ... @@ -29,6 +45,7 @@ class Environment &lt; ActiveRecord::Base
29 45 'manage_environment_roles' => N_('Manage environment roles'),
30 46 'manage_environment_validators' => N_('Manage environment validators'),
31 47 'manage_environment_users' => N_('Manage environment users'),
  48 + 'manage_environment_organizations' => N_('Manage environment organizations'),
32 49 'manage_environment_templates' => N_('Manage environment templates'),
33 50 'manage_environment_licenses' => N_('Manage environment licenses'),
34 51 'manage_environment_trusted_sites' => N_('Manage environment trusted sites'),
... ... @@ -74,7 +91,8 @@ class Environment &lt; ActiveRecord::Base
74 91 'edit_profile_design',
75 92 'manage_products',
76 93 'manage_friends',
77   - 'perform_task'
  94 + 'perform_task',
  95 + 'view_tasks'
78 96 ]
79 97 )
80 98 end
... ...
app/models/event.rb
... ... @@ -98,47 +98,19 @@ class Event &lt; Article
98 98 start_date..(end_date||start_date)
99 99 end
100 100  
101   - # FIXME this shouldn't be needed
102   - include ActionView::Helpers::TagHelper
103   - include ActionView::Helpers::UrlHelper
104   - include DatesHelper
  101 + def first_paragraph
  102 + paragraphs = Nokogiri::HTML.fragment(self.body).css('p')
  103 + paragraphs.empty? ? '' : paragraphs.first.to_html
  104 + end
105 105  
106 106 def to_html(options = {})
  107 + event = self
  108 + format = options[:format]
107 109  
108   - result = ''
109   - html = ::Builder::XmlMarkup.new(:target => result)
110   -
111   - html.div(:class => 'event-info' ) {
112   - html.ul(:class => 'event-data' ) {
113   - html.li(:class => 'event-dates' ) {
114   - html.span _('When:')
115   - html.text! show_period(start_date, end_date)
116   - } if start_date.present? || end_date.present?
117   - html.li {
118   - html.span _('URL:')
119   - html.a(self.link || "", 'href' => self.link || "")
120   - } if self.link.present?
121   - html.li {
122   - html.span _('Address:')
123   - html.text! self.address || ""
124   - } if self.address.present?
125   - }
126   -
127   - # TODO: some good soul, please clean this ugly hack:
128   - if self.body
129   - html.div('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', :class => 'event-description')
130   - end
131   - }
132   -
133   - if self.body
134   - if options[:format] == 'short'
135   - result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', display_short_format(self))
136   - else
137   - result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', self.body)
138   - end
  110 + proc do
  111 + render :file => 'content_viewer/event_page', :locals => { :event => event,
  112 + :format => format }
139 113 end
140   -
141   - result
142 114 end
143 115  
144 116 def duration
... ...
app/models/image.rb
... ... @@ -23,7 +23,7 @@ class Image &lt; ActiveRecord::Base
23 23  
24 24 postgresql_attachment_fu
25 25  
26   - attr_accessible :uploaded_data
  26 + attr_accessible :uploaded_data, :label
27 27  
28 28 def current_data
29 29 File.file?(full_filename) ? File.read(full_filename) : nil
... ...
app/models/organization.rb
... ... @@ -147,6 +147,12 @@ class Organization &lt; Profile
147 147 ]
148 148 end
149 149  
  150 + def short_name chars = 40
  151 + s = self.display_name
  152 + s = super(chars) if s.blank?
  153 + s
  154 + end
  155 +
150 156 def notification_emails
151 157 emails = [contact_email].select(&:present?) + admins.map(&:email)
152 158 if emails.empty?
... ...
app/models/person.rb
... ... @@ -84,9 +84,9 @@ roles] }
84 84 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
85 85 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions'
86 86  
87   - has_many :profile_suggestions, :foreign_key => :person_id, :order => 'score DESC', :dependent => :destroy
88   - has_many :suggested_people, :through => :profile_suggestions, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Person', true]
89   - has_many :suggested_communities, :through => :profile_suggestions, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Community', true]
  87 + has_many :suggested_profiles, :class_name => 'ProfileSuggestion', :foreign_key => :person_id, :order => 'score DESC', :dependent => :destroy
  88 + has_many :suggested_people, :through => :suggested_profiles, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Person', true]
  89 + has_many :suggested_communities, :through => :suggested_profiles, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Community', true]
90 90  
91 91 scope :more_popular, :order => 'friends_count DESC'
92 92  
... ... @@ -103,6 +103,8 @@ roles] }
103 103  
104 104 belongs_to :user, :dependent => :delete
105 105  
  106 + acts_as_voter
  107 +
106 108 def can_change_homepage?
107 109 !environment.enabled?('cant_change_homepage') || is_admin?
108 110 end
... ... @@ -522,7 +524,7 @@ roles] }
522 524 end
523 525  
524 526 def remove_suggestion(profile)
525   - suggestion = profile_suggestions.find_by_suggestion_id profile.id
  527 + suggestion = suggested_profiles.find_by_suggestion_id profile.id
526 528 suggestion.disable if suggestion
527 529 end
528 530  
... ...
app/models/product_category.rb
... ... @@ -10,6 +10,9 @@ class ProductCategory &lt; Category
10 10 :joins => :products,
11 11 :conditions => ['products.profile_id = ?', enterprise.id]
12 12 }}
  13 + scope :by_environment, lambda { |environment| {
  14 + :conditions => ['environment_id = ?', environment.id]
  15 + }}
13 16 scope :unique_by_level, lambda { |level| {
14 17 :select => "DISTINCT ON (filtered_category) split_part(path, '/', #{level}) AS filtered_category, categories.*"
15 18 }}
... ...
app/models/profile.rb
... ... @@ -71,6 +71,7 @@ class Profile &lt; ActiveRecord::Base
71 71 'manage_friends' => N_('Manage friends'),
72 72 'validate_enterprise' => N_('Validate enterprise'),
73 73 'perform_task' => N_('Perform task'),
  74 + 'view_tasks' => N_('View tasks'),
74 75 'moderate_comments' => N_('Moderate comments'),
75 76 'edit_appearance' => N_('Edit appearance'),
76 77 'view_private_content' => N_('View private content'),
... ... @@ -392,6 +393,9 @@ class Profile &lt; ActiveRecord::Base
392 393 new_block = block.class.new(:title => block[:title])
393 394 new_block.copy_from(block)
394 395 new_box.blocks << new_block
  396 + if block.mirror?
  397 + block.add_observer(new_block)
  398 + end
395 399 end
396 400 end
397 401 end
... ... @@ -1021,7 +1025,7 @@ private :generate_url, :url_options
1021 1025 end
1022 1026  
1023 1027 def remove_from_suggestion_list(person)
1024   - suggestion = person.profile_suggestions.find_by_suggestion_id self.id
  1028 + suggestion = person.suggested_profiles.find_by_suggestion_id self.id
1025 1029 suggestion.disable if suggestion
1026 1030 end
1027 1031  
... ...
app/models/profile_suggestion.rb
... ... @@ -113,14 +113,14 @@ class ProfileSuggestion &lt; ActiveRecord::Base
113 113 suggested_profiles = all_suggestions(person)
114 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 117 suggested_profiles = suggested_profiles.where("profiles.id NOT IN (#{already_suggested_profiles})") if already_suggested_profiles.present?
118 118 #TODO suggested_profiles = suggested_profiles.order('score DESC')
119 119 suggested_profiles = suggested_profiles.limit(N_SUGGESTIONS)
120 120 return if suggested_profiles.blank?
121 121  
122 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 124 RULES.each do |rule, options|
125 125 begin
126 126 value = suggested_profile.send("#{rule}_count").to_i
... ... @@ -273,7 +273,7 @@ class ProfileSuggestion &lt; ActiveRecord::Base
273 273 end
274 274  
275 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 277 Delayed::Job.enqueue ProfileSuggestionsJob.new(person.id) unless ProfileSuggestionsJob.exists?(person.id)
278 278 end
279 279  
... ...
app/models/task.rb
... ... @@ -33,6 +33,8 @@ class Task &lt; ActiveRecord::Base
33 33  
34 34 belongs_to :requestor, :class_name => 'Profile', :foreign_key => :requestor_id
35 35 belongs_to :target, :foreign_key => :target_id, :polymorphic => true
  36 + belongs_to :responsible, :class_name => 'Person', :foreign_key => :responsible_id
  37 + belongs_to :closed_by, :class_name => 'Person', :foreign_key => :closed_by_id
36 38  
37 39 validates_uniqueness_of :code, :on => :create
38 40 validates_presence_of :code
... ... @@ -76,11 +78,9 @@ class Task &lt; ActiveRecord::Base
76 78 # this method finished the task. It calls #perform, which must be overriden
77 79 # by subclasses. At the end a message (as returned by #finish_message) is
78 80 # sent to the requestor with #notify_requestor.
79   - def finish
  81 + def finish(closed_by=nil)
80 82 transaction do
81   - self.status = Task::Status::FINISHED
82   - self.end_date = Time.now
83   - self.save!
  83 + close(Task::Status::FINISHED, closed_by)
84 84 self.perform
85 85 begin
86 86 send_notification(:finished)
... ... @@ -105,11 +105,9 @@ class Task &lt; ActiveRecord::Base
105 105  
106 106 # this method cancels the task. At the end a message (as returned by
107 107 # #cancel_message) is sent to the requestor with #notify_requestor.
108   - def cancel
  108 + def cancel(closed_by=nil)
109 109 transaction do
110   - self.status = Task::Status::CANCELLED
111   - self.end_date = Time.now
112   - self.save!
  110 + close(Task::Status::CANCELLED, closed_by)
113 111 begin
114 112 send_notification(:cancelled)
115 113 rescue NotImplementedError => ex
... ... @@ -118,6 +116,13 @@ class Task &lt; ActiveRecord::Base
118 116 end
119 117 end
120 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 +
121 126 # Here are the tasks customizable options.
122 127  
123 128 def title
... ... @@ -239,9 +244,9 @@ class Task &lt; ActiveRecord::Base
239 244 scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] }
240 245 scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} }
241 246 scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} }
242   - scope :like, ->(field,value) { where("LOWER(#{field}) LIKE ?", "%#{value.downcase}%") if value}
243   - scope :pending_all, ->(profile, params){
244   - self.to(profile).without_spam.pending.of(params[:filter_type]).like('data', params[:filter_text])
  247 + scope :like, lambda { |field, value| where("LOWER(#{field}) LIKE ?", "%#{value.downcase}%") if value}
  248 + scope :pending_all, lambda { |profile, filter_type, filter_text|
  249 + self.to(profile).without_spam.pending.of(filter_type).like('data', filter_text)
245 250 }
246 251  
247 252 scope :to, lambda { |profile|
... ...
app/models/uploaded_file.rb
1   -require 'short_filename'
2   -
3 1 # Article type that handles uploaded files.
4 2 #
5 3 # Limitation: only file metadata are versioned. Only the latest version
... ... @@ -14,8 +12,6 @@ class UploadedFile &lt; Article
14 12  
15 13 track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? }, :custom_target => :parent
16 14  
17   - include ShortFilename
18   -
19 15 def title
20 16 if self.name.present? then self.name else self.filename end
21 17 end
... ... @@ -65,7 +61,7 @@ class UploadedFile &lt; Article
65 61 # :min_size => 2.megabytes
66 62 # :max_size => 5.megabytes
67 63 has_attachment :storage => :file_system,
68   - :thumbnails => { :icon => [24,24], :thumb => '130x130>', :slideshow => '320x240>', :display => '640X480>' },
  64 + :thumbnails => { :icon => [24,24], :bigicon => [50,50], :thumb => '130x130>', :slideshow => '320x240>', :display => '640X480>' },
69 65 :thumbnail_class => Thumbnail,
70 66 :max_size => self.max_size
71 67  
... ...
app/models/user.rb
... ... @@ -67,7 +67,8 @@ class User &lt; ActiveRecord::Base
67 67  
68 68 attr_writer :person_data
69 69 def person_data
70   - @person_data || {}
  70 + @person_data = {} if @person_data.nil?
  71 + @person_data
71 72 end
72 73  
73 74 def email_domain
... ... @@ -320,6 +321,8 @@ class User &lt; ActiveRecord::Base
320 321  
321 322 {
322 323 'login' => self.login,
  324 + 'name' => self.person.name,
  325 + 'email' => self.email,
323 326 'avatar' => self.person.profile_custom_icon(gravatar_default),
324 327 'is_admin' => self.person.is_admin?,
325 328 'since_month' => self.person.created_at.month,
... ...
app/presenters/image.rb
... ... @@ -4,6 +4,10 @@ class FilePresenter::Image &lt; FilePresenter
4 4 f.image? ? 10 : nil
5 5 end
6 6  
  7 + def sized_icon(size)
  8 + public_filename size
  9 + end
  10 +
7 11 def icon_name
8 12 public_filename :icon
9 13 end
... ...
app/views/admin_panel/_site_info.html.erb
... ... @@ -3,6 +3,21 @@
3 3 <%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %>
4 4 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %>
5 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 21 <%= required f.text_field(:reports_lower_bound, :size => 3) %>
7 22 <%= labelled_form_field(_('Default language'), select(:environment, :default_language, environment.locales.invert, { :selected => environment.default_locale, :include_blank => true })) %>
8 23 <%= label_tag :languages, _('Available languages') %>
... ...
app/views/admin_panel/index.html.erb
... ... @@ -18,9 +18,9 @@
18 18 <table>
19 19 <tr><td><%= link_to _('User roles'), :controller => 'role' %></td></tr>
20 20 <tr><td><%= link_to _('Users'), :controller => 'users' %></td></tr>
  21 + <tr><td><%= link_to _('Organizations'), :controller => 'organizations' %></td></tr>
21 22 <tr><td><%= link_to _('Profile templates'), :controller => 'templates' %></td></tr>
22 23 <tr><td><%= link_to _('Fields'), :controller => 'features', :action => 'manage_fields' %></td></tr>
23   - <tr><td><%= link_to _('Manage organizations status'), :action => 'manage_organizations_status' %></td></tr>
24 24 </table>
25 25  
26 26  
... ...
app/views/admin_panel/manage_organizations_status.html.erb
... ... @@ -1,69 +0,0 @@
1   -<h1><%= _('Manage organizations') %></h1>
2   -
3   -<%= form_tag( { :action => 'manage_organizations_status' }, :method => 'get', :class => 'users-search' ) do %>
4   -
5   - <div class="search-field">
6   - <span class="formfield">
7   - <%= text_field_tag 'q', @q, :title => _("Find profiles"), :style=>"width:85%" %>
8   - </span>
9   -
10   - <%= submit_button(:search, _('Search')) %>
11   - </div>
12   -
13   - <div class="environment-users-results-header">
14   - <div id='environment-users-filter-title'><%= @title %></div>
15   -
16   - <div id="environment-users-filter-filter">
17   - <strong><%= _("Filter by: ") %></strong>
18   -
19   - <select id="profile_filter_select">
20   - <%= options_for_select([['Any', 'any'],["Disabled profiles", "disabled"], ["Enabled profiles", "enabled"]], @filter) %>
21   - </select>
22   - </div>
23   - <div style="clear: both"></div>
24   - </div>
25   -
26   - <table>
27   - <colgroup>
28   - <col width="80%">
29   - <col width="20%">
30   - </colgroup>
31   -
32   - <tr>
33   - <th><%= _('Member') %></th>
34   - <th><%= _('Actions') %></th>
35   - </tr>
36   -
37   - <% @collection.each do |p| %>
38   - <tr title="<%= p.name %>">
39   - <td><%= link_to_profile p.short_name, p.identifier, :title => p.name %> </td>
40   -
41   - <td class='actions'>
42   - <div class="members-buttons-cell">
43   - <% if p.visible %>
44   - <%= button_without_text :'deactivate-user', _('Deactivate'), {:controller => "profile_editor", :action => 'deactivate_profile', :profile => p.identifier, :id => p.id}, :confirm => _("Do you want to deactivate this profile ?") %>
45   - <% else %>
46   - <%= button_without_text :'activate-user', _('Activate'), {:controller => "profile_editor", :action => 'activate_profile', :profile => p.identifier, :id => p.id}, :confirm => _("Do you want to activate this profile ?") %>
47   - <% end %>
48   - <%= button_without_text :'delete', _('Remove'), {:controller => "profile_editor", :action => 'destroy_profile', :profile => p.identifier, :id => p.id, :return_to => "/admin/admin_panel/manage_organizations_status"}, :method => :post, :confirm => _("Do you want to deactivate this profile ?") %>
49   - </div>
50   - </td>
51   - </tr>
52   - <% end %>
53   - </table>
54   -
55   -<% end %>
56   -
57   -<%= pagination_links @collection, {:param_name => 'npage', :page_links => true} %>
58   -
59   -<% button_bar do %>
60   - <%= button :back, _('Back'), :controller => 'admin_panel' %>
61   -<% end %>
62   -
63   -<script type="text/javascript">
64   - jQuery(document).ready(function(){
65   - jQuery("#profile_filter_select").change(function(){
66   - document.location.href = '/admin/admin_panel/manage_organizations_status?filter='+this.value;
67   - });
68   - });
69   -</script>
70 0 \ No newline at end of file
app/views/blocks/profile_info_actions/_common.html.erb 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +<li><%= report_abuse(profile, :button) %></li>
  2 +<%= render_environment_features(:profile_actions) %>
... ...
app/views/blocks/profile_info_actions/_community.html.erb
... ... @@ -13,8 +13,6 @@
13 13 </li>
14 14 <% end %>
15 15  
16   - <li><%= report_abuse(profile, :button) %></li>
17   -
18   - <%= render_environment_features(:profile_actions) %>
  16 + <%= render :partial => 'blocks/profile_info_actions/common' %>
19 17 <% end %>
20 18 </ul>
... ...
app/views/blocks/profile_info_actions/_enterprise.html.erb
... ... @@ -8,5 +8,5 @@
8 8 <li><%= button(:'menu-mail', _('Send an e-mail'), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, {:id => 'enterprise-contact-button'} ) %></li>
9 9 <% end %>
10 10  
11   - <li><%= report_abuse(profile, :button) %></li>
  11 + <%= render :partial => 'blocks/profile_info_actions/common' %>
12 12 </ul>
... ...
app/views/blocks/profile_info_actions/_person.html.erb
... ... @@ -11,6 +11,6 @@
11 11 <li><%= button(:back, _('Send an e-mail'), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}) %></li>
12 12 <% end %>
13 13  
14   - <li><%= report_abuse(profile, :button) %></li>
  14 + <%= render :partial => 'blocks/profile_info_actions/common' %>
15 15 <% end %>
16 16 </ul>
... ...
app/views/box_organizer/edit.html.erb
... ... @@ -28,6 +28,12 @@
28 28 </div>
29 29 <% end %>
30 30  
  31 + <% if @block.owner.kind_of?(Profile) && @block.owner.is_template? %>
  32 + <div class="mirror_block">
  33 + <%= labelled_check_box(_("Mirror"), "block[mirror]", value = "1", checked = @block.mirror) %>
  34 + </div>
  35 + <% end %>
  36 +
31 37 <% button_bar do %>
32 38 <%= submit_button(:save, _('Save')) %>
33 39 <%= modal_close_button(_('Cancel')) %>
... ...
app/views/chat/start_session_error.html.erb
1 1 <p>
2 2 <%= ui_icon('ui-icon-alert') %>
3   -<%= _('Could not connect to chat') %>, <a id='chat-retry' href='#' data-jid='<%= user.jid %>'><%= _('try again') %></a>.
  3 +<%= _('Could not connect to chat') %>, <a id='chat-retry' href='' data-jid='<%= user.jid %>'><%= _('try again') %></a>.
4 4 </p>
... ...
app/views/cms/_blog.html.erb
... ... @@ -67,7 +67,8 @@
67 67 <%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [
68 68 [ _('Full post'), 'full'],
69 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 74 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %>
... ...
app/views/cms/_view_items.html.erb 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +<% @articles.each do |article| article = FilePresenter.for article %>
  2 + <tr title="<%= article.title%>" >
  3 + <td class="article-name">
  4 + <%= link_to_article(article) %>
  5 + </td>
  6 + <% short_description = article.respond_to?(:short_description) ?
  7 + article.short_description :
  8 + article.class.short_description %>
  9 + <td class="article-mime" title=<%= short_description.to_json %>>
  10 + <%= short_description %>
  11 + </td>
  12 + <td class="last-update">
  13 + <%= time_ago_in_words article.updated_at %>
  14 + </td>
  15 + <td class="article-controls">
  16 + <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %>
  17 + <%= button_without_text :eyes, _('Public view'), article.view_url %>
  18 + <%= display_spread_button(article) unless remove_content_button(:spread, article) %>
  19 + <% if user.can_change_homepage? && !remove_content_button(:home, article) %>
  20 + <% if profile.home_page != article %>
  21 + <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>
  22 + <% else %>
  23 + <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>
  24 + <% end %>
  25 + <% end %>
  26 + <%= display_delete_button(article) if !remove_content_button(:delete, article) %>
  27 + </td>
  28 + </tr>
  29 +<% end %>
... ...
app/views/cms/view.html.erb
... ... @@ -37,6 +37,7 @@
37 37 <tr>
38 38 <th><%= _('Name') %></th>
39 39 <th><%= _('Type') %></th>
  40 + <th><%= _('Last update') %></th>
40 41 <th><%= _('Actions') %></th>
41 42 </tr>
42 43  
... ... @@ -54,32 +55,7 @@
54 55 </tr>
55 56 <% end %>
56 57  
57   - <% @articles.each do |article| article = FilePresenter.for article %>
58   - <tr title="<%= article.title%>" >
59   - <td class="article-name">
60   - <%= link_to_article(article) %>
61   - </td>
62   - <% short_description = article.respond_to?(:short_description) ?
63   - article.short_description :
64   - article.class.short_description %>
65   - <td class="article-mime" title=<%= short_description.to_json %>>
66   - <%= short_description %>
67   - </td>
68   - <td class="article-controls">
69   - <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %>
70   - <%= button_without_text :eyes, _('Public view'), article.view_url %>
71   - <%= display_spread_button(article) unless remove_content_button(:spread, article) %>
72   - <% if user.can_change_homepage? && !remove_content_button(:home, article) %>
73   - <% if profile.home_page != article %>
74   - <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>
75   - <% else %>
76   - <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>
77   - <% end %>
78   - <% end %>
79   - <%= display_delete_button(article) if !remove_content_button(:delete, article) %>
80   - </td>
81   - </tr>
82   - <% end %>
  58 + <%= render 'view_items' %>
83 59  
84 60 </table>
85 61  
... ...
app/views/content_viewer/_article_title.html.erb 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +<% if @page.belongs_to_blog? || @page.belongs_to_forum?%>
  2 + <h1 class="title">
  3 + <% if no_link %>
  4 + <%= h(@page.title) %>
  5 + <% else %>
  6 + <%= link_to(@page.name, @page.url) %>
  7 + <% end %>
  8 + </h1>
  9 + <%= render :partial => "publishing_info" %>
  10 + <% unless @page.abstract.blank? %>
  11 + <div class="preview">
  12 + <%= @page.lead %>
  13 + </div>
  14 + <% end %>
  15 +<% else %>
  16 + <h1 class="title">
  17 + <%= h(@page.title) %>
  18 + </h1>
  19 + <%= render :partial => "publishing_info" %>
  20 +<% end %>
... ...
app/views/content_viewer/_article_toolbar.html.erb
... ... @@ -30,6 +30,10 @@
30 30 <% end %>
31 31  
32 32 <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new, @page) %>
  33 +
  34 + <% content = content_tag('span', label_for_clone_article(@page)) %>
  35 + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :type => @page.class }) %>
  36 + <%= expirable_button @page, :clone, content, url %>
33 37 <% end %>
34 38  
35 39 <% if @page.accept_uploads? && @page.allow_create?(user) %>
... ... @@ -58,9 +62,9 @@
58 62 <% if @page.blog? and !@page.image.nil? %>
59 63 <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div>
60 64 <% end %>
61   - <%= 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 %>
62 66 <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
63   - <%= article_title(@page, :no_link => true) %>
  67 + <%= render :partial => 'article_title', :locals => {:no_link => true} %>
64 68 <%= article_translations(@page) %>
65 69 </div>
66 70 </div>
... ...
app/views/content_viewer/_display_compact_format.html.erb 0 → 100644
... ... @@ -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.lead(400) %>
  20 + </div>
  21 +</div>
... ...
app/views/content_viewer/_publishing_info.html.erb 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +<span class="publishing-info">
  2 + <span class="date">
  3 + <%= show_date(@page.published_at) %>
  4 + </span>
  5 + <span class="author">
  6 + <%= _(", by %s") % (@page.author ? link_to(@page.author_name, @page.author_url) : @page.author_name) %>
  7 + </span>
  8 +<% unless @no_comments %>
  9 + <span class="comments">
  10 + <%= (" - %s") % link_to_comments(@page)%>
  11 + </span>
  12 +<% end %>
  13 +</span>
  14 +
  15 +<% if @page.display_hits? || @page.license.present? %>
  16 + <div id='article-sub-header'>
  17 + <% if @page.display_hits? %>
  18 + <div id="article-hits">
  19 + <%= n_('Viewed one time', 'Viewed %{num} times', @page.hits) % { :num => @page.hits } %>
  20 + </div>
  21 + <% end %>
  22 +
  23 + <% if @page.license.present? %>
  24 + <div id="article-license">
  25 + <%= _('Licensed under %s') % (@page.license.url.present? ? link_to(@page.license.name, @page.license.url, :target => '_blank') : @page.license.name) %>
  26 + </div>
  27 + <% end %>
  28 + </div>
  29 +<% end %>
... ...
app/views/content_viewer/blog_page.html.erb
... ... @@ -8,7 +8,7 @@
8 8 </div>
9 9 </div>
10 10 <hr class="pre-posts"/>
11   -<div class="blog-posts">
  11 +<div class="blog-posts page-<%= @npage %>">
12 12 <% paginate = true %>
13 13 <%=
14 14 posts = @posts
... ...
app/views/content_viewer/event_page.html.erb 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +<div class="event-card">
  2 + <div class="event-image">
  3 + <% if event.image %>
  4 + <%= image_tag(event.image.public_filename(:big)) %>
  5 + <% end %>
  6 + </div>
  7 + <div class="about-event">
  8 + <% if event.start_date.present? || event.end_date.present? %>
  9 + <span class="event-date">
  10 + <%= show_period(event.start_date, event.end_date) %>
  11 + </span>
  12 + <% end %>
  13 + <% if event.link.present? %>
  14 + <span class="event-link">
  15 + <%= link_to event.link, event.link %>
  16 + </span>
  17 + <% end %>
  18 + <% if event.address.present? %>
  19 + <span class="event-address">
  20 + <span>
  21 + <%= event.address %>
  22 + </span>
  23 + </span>
  24 + <% end %>
  25 + </div>
  26 +</div>
  27 +
  28 +<div class="event-body">
  29 + <% if format == 'short' %>
  30 + <%= display_short_format event, :comments_link => false, :read_more_link => false %>
  31 + <% else %>
  32 + <% unless event.abstract.blank? %>
  33 + <div class="event-lead">
  34 + <%= event.article_lead %>
  35 + </div>
  36 + <% end %>
  37 + <div class="event-content">
  38 + <%= event.body %>
  39 + </div>
  40 + <% end %>
  41 +</div>
... ...
app/views/content_viewer/folder.html.erb
1 1 <% unless folder.body.blank? %>
2   - <div>
  2 + <div class="folder-description">
3 3 <%= folder.body %>
4 4 </div>
5   - <hr/>
6 5 <% end %>
7 6  
8 7 <% if folder.children.empty? %>
... ...
app/views/content_viewer/view_page.html.erb
... ... @@ -24,22 +24,6 @@
24 24 <%= render :partial => 'article_toolbar' %>
25 25 </div>
26 26  
27   -<% if @page.display_hits? || @page.license.present? %>
28   - <div id='article-sub-header'>
29   - <% if @page.display_hits? %>
30   - <div id="article-hits">
31   - <%= n_('Viewed one time', 'Viewed %{num} times', @page.hits) % { :num => @page.hits } %>
32   - </div>
33   - <% end %>
34   -
35   - <% if @page.license.present? %>
36   - <div id="article-license">
37   - <%= _('Licensed under %s') % (@page.license.url.present? ? link_to(@page.license.name, @page.license.url, :target => '_blank') : @page.license.name) %>
38   - </div>
39   - <% end %>
40   - </div>
41   -<% end %>
42   -
43 27 <% if NOOSFERO_CONF['addthis_enabled'] %>
44 28 <%= render :partial => 'addthis' %>
45 29 <% end %>
... ... @@ -47,6 +31,12 @@
47 31 <% cache(@page.cache_key(params, user, language)) do %>
48 32 <div class="<%="article-body article-body-" + @page.css_class_name %>">
49 33 <% options = @page.image? ? {:gallery_view => true} : {} %>
  34 + <% if @page.image.present? && !@page.event? %>
  35 + <div class="article-body-img">
  36 + <%= image_tag(@page.image.public_filename) %>
  37 + <p><%= @page.image.label%></p>
  38 + </div>
  39 + <% end %>
50 40 <%= article_to_html(@page, options) %>
51 41 <br style="clear:both" />
52 42 </div> <!-- end class="article-body" -->
... ...
app/views/layouts/application-ng.html.erb
... ... @@ -27,6 +27,7 @@
27 27  
28 28 <script type="text/javascript">
29 29 DEFAULT_LOADING_MESSAGE = <%="'#{ _('loading...') }'" %>;
  30 + noosfero.profile = <%= (@profile.identifier if @profile).to_json %>
30 31 </script>
31 32  
32 33 </head>
... ...
app/views/manage_products/_categories_autocomplete.html.erb 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<%= text_field_tag 'product_category_id', '', :placeholder => _('type a category for the product') %>
  2 +
  3 +<%= javascript_include_tag '/javascripts/product_categories.js' %>
  4 +<%= javascript_tag do %>
  5 + product_categories.autocomplete.search_url = <%= url_for(:controller => :manage_products, :action => :search_categories).to_json %>
  6 + product_categories.autocomplete.select_url = <%= url_for(:controller => :manage_products, :action => :show_category_tree).to_json %>
  7 + product_categories.autocomplete.load('#product_category_id')
  8 +<% end %>
... ...
app/views/manage_products/_selected_category_tree.html.erb 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +<%= categories_container selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true) %>
  2 +
... ...
app/views/manage_products/edit_category.html.erb
... ... @@ -16,7 +16,7 @@
16 16  
17 17 <h3><%= _('Edit category of this product:') %></h3>
18 18  
19   - <%= categories_container(selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true)) %>
  19 + <%= render 'manage_products/selected_category_tree' %>
20 20  
21 21 <div id='categories_selection_actionbar'>
22 22 <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %>
... ...
app/views/organizations/_results.html.erb 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +<div class='results'>
  2 + <table id='organizations-list'>
  3 + <colgroup>
  4 + <col width="60%">
  5 + <col width="20%">
  6 + <col width="20%">
  7 + </colgroup>
  8 +
  9 + <tr>
  10 + <th><%= _('Profile') %></th>
  11 + <th><%= _('Actions') %></th>
  12 + <th><%= _('Type') %>
  13 +
  14 + <%= select_tag(:type, options_for_select(@types_filter, @type)) %>
  15 + </th>
  16 + </tr>
  17 +
  18 + <% @collection.each do |p| %>
  19 + <tr title="<%= p.name %>">
  20 + <td><%= link_to_profile p.short_name, p.identifier, :title => p.name %> </td>
  21 +
  22 + <td class='actions'>
  23 + <div class="members-buttons-cell">
  24 + <% if p.visible %>
  25 + <%= button_without_text :'deactivate-user', _('Deactivate'), {:action => 'deactivate', :id => p.id}, :class => 'action', 'data-confirm' => _("Do you want to deactivate this organization?") %>
  26 + <% else %>
  27 + <%= button_without_text :'activate-user', _('Activate'), {:action => 'activate', :id => p.id}, :class => 'action', 'data-confirm' => _("Do you want to activate this organization?") %>
  28 + <% end %>
  29 + <%= button_without_text :'delete', _('Remove'), {:action => 'destroy', :id => p.id}, :class => 'action', 'data-method' => :post, 'data-confirm' => _("Do you want to destroy this organization?") %>
  30 + </div>
  31 + </td>
  32 +
  33 + <td> <%= _("#{p.type}") %> </td>
  34 + </tr>
  35 + <% end %>
  36 + </table>
  37 +
  38 + <div>
  39 + <%= pagination_links @collection, {:param_name => 'npage', :page_links => true} %>
  40 + </div>
  41 +</div>
... ...
app/views/organizations/index.html.erb 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +<h1><%= _('Organizations') %></h1>
  2 +
  3 +<%= form_tag( { :action => 'index' }, :method => 'get', :id => 'manage-profiles' ) do %>
  4 +
  5 + <div class="search-field">
  6 + <span class="formfield">
  7 + <%= text_field_tag 'q', @q, :title => _('Find organizations'), :style=>"width:85%" %>
  8 + </span>
  9 +
  10 + <%= submit_button(:search, _('Search')) %>
  11 + </div>
  12 +
  13 + <div class="environment-profiles-results-header">
  14 + <div id='environment-profiles-filter-title'><%= @title %></div>
  15 +
  16 + <div id="environment-profiles-filter-filter">
  17 + <strong><%= _("Filter by: ") %></strong>
  18 + <%= select_tag(:filter, options_for_select([[_('Any'), 'any'],[_('Disabled'), "disabled"], [_('Enabled') , "enabled"]], @filter)) %>
  19 + </div>
  20 + <div style="clear: both"></div>
  21 + </div>
  22 +
  23 + <%= render :partial => 'results' %>
  24 +
  25 + <% button_bar do %>
  26 + <%= button :back, _('Back'), :controller => 'admin_panel' %>
  27 + <% end %>
  28 +<% end %>
  29 +
  30 +<%= javascript_include_tag 'manage-organizations' %>
... ...
app/views/organizations/index.js.erb 0 → 120000
... ... @@ -0,0 +1 @@
  1 +../../views/shared/admin/profiles/index.js.rb
0 2 \ No newline at end of file
... ...
app/views/person_notifier/mailer/_comment.html.erb
... ... @@ -19,7 +19,7 @@
19 19 <span style="font-size: 12px;"><%= comment.title %></span><br/>
20 20 <% end %>
21 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 23 <br style="clear: both;" />
24 24  
25 25 <% unless comment.replies.blank? %>
... ...
app/views/person_notifier/mailer/_create_article.html.erb
... ... @@ -6,7 +6,7 @@
6 6 <p>
7 7 <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span>
8 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 10 </p>
11 11 <p>
12 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 5 <td>
6 6 <p>
7 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 9 </p>
10 10 </td>
11 11 </tr>
... ...
app/views/person_notifier/mailer/_task.html.erb
... ... @@ -12,7 +12,7 @@
12 12 <span style="font-size: 14px">
13 13 <%= task_information(task) %>
14 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 16 </div>
17 17 </td>
18 18 </tr>
... ...
app/views/person_notifier/mailer/_upload_image.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <td>
6 6 <p>
7 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 9 </p>
10 10 </td>
11 11 </tr>
... ...
app/views/profile/_comment.html.erb
... ... @@ -40,7 +40,7 @@
40 40 <%= txt2html comment.body %>
41 41 </div>
42 42 <div class="profile-activity-time">
43   - <%= time_ago_as_sentence(comment.created_at) %>
  43 + <%= time_ago_in_words(comment.created_at) %>
44 44 </div>
45 45 </div>
46 46  
... ...
app/views/profile/_create_article.html.erb
... ... @@ -12,7 +12,7 @@
12 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 13 </div>
14 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 16 <div class='profile-wall-actions'>
17 17 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %>
18 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 3 </div>
4 4 <div class='profile-activity-description'>
5 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 7 <div class='profile-wall-actions'>
8 8 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %>
9 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 3 </div>
4 4 <div class='profile-activity-description'>
5 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 7 <div class='profile-wall-actions'>
8 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 9 </div>
... ...
app/views/profile/_profile_scrap.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <div class='profile-activity-description'>
6 6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
7 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 9 <div class='profile-wall-actions'>
10 10 <% if logged_in? && current_person.follows?(scrap.sender) %>
11 11 <span class='profile-activity-send-reply'>
... ... @@ -22,5 +22,5 @@
22 22 <% end %>
23 23 </ul>
24 24 <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %>
25   - <hr />
  25 + <hr />
26 26 </li>
... ...
app/views/profile/_profile_scraps.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <div class='profile-activity-description'>
6 6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
7 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 9 <div class='profile-wall-actions'>
10 10 <% if logged_in? && current_person.follows?(scrap.sender) %>
11 11 <span class='profile-activity-send-reply'>
... ...
app/views/profile/_upload_image.html.erb
... ... @@ -4,7 +4,7 @@
4 4 </div>
5 5 <div class='profile-activity-description'>
6 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 8 <div class='profile-wall-actions'>
9 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 10 </div>
... ...
app/views/profile/content_tagged.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <h1><%= _('Content tagged with "%s"') % escaped_tag %></h1>
6 6  
7 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 9 </p>
10 10  
11 11 <% cache_timeout(@tag_cache_key, 4.hour) do %>
... ...
app/views/profile_editor/index.html.erb
... ... @@ -73,7 +73,7 @@
73 73 <%= control_panel_button(_('Edit welcome page'), 'welcome-page', :action => 'welcome_page') if has_welcome_page %>
74 74  
75 75 <% @plugins.dispatch(:control_panel_buttons).each do |button| %>
76   - <%= control_panel_button(button[:title], button[:icon], button[:url]) %>
  76 + <%= control_panel_button(button[:title], button[:icon], button[:url], button[:html_options]) %>
77 77 <% end %>
78 78  
79 79 <% end %>
... ...
app/views/shared/_change_image.html.erb
1   - <%= i.file_field( :uploaded_data, { :onchange => 'updateImg(this.value)' } ) %>
2   - <%= button_to_function(:cancel,_('Cancel'),"jQuery('#change-image-link').show(); jQuery('#change-image').html('')", :id => 'cancel-change-image-link', :style => 'display: none')%>
  1 +<%= i.file_field( :uploaded_data, { :onchange => 'updateImg(this.value)' } ) %>
  2 +<%= labelled_form_field(_("Image Label:"), i.text_field(:label)) %>
  3 +<%= button_to_function(:cancel,_('Cancel'),"jQuery('#change-image-link').show(); jQuery('#change-image').html('')", :id => 'cancel-change-image-link', :style => 'display: none')%>
... ...
app/views/shared/_content_item.html.erb 0 → 100644
... ... @@ -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(content.name, content.url) %>
  8 + </span>
  9 + <span class="item-date"><%= _("Published at: #{show_date(content.updated_at)}") %></span>
  10 + </div>
  11 +</div>
... ...
app/views/shared/_lead_and_body.html.erb
... ... @@ -19,17 +19,27 @@
19 19  
20 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 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 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 31 <% end %>
27 32 </div>
28 33 <div style="margin-top: 10px;">
  34 + <% body_options = {:style => 'width: 100%; height: 400px;', :class => editor_type} %>
29 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 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 43 <% end %>
34 44 </div>
35 45  
... ...
app/views/shared/admin/profiles/index.js.rb 0 → 100644
... ... @@ -0,0 +1 @@
  1 +jQuery('#manage-profiles .results').replaceWith('<%= escape_javascript(render 'results') %>');
... ...
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 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 8 <% end %>
11   -</table>
  9 +</ul>
12 10  
13 11 <p><%= pagination_links contents, :param_name => 'npage', :page_links => true %></p>
... ...
app/views/shared/logged_in/xmpp_chat.html.erb
... ... @@ -7,13 +7,13 @@
7 7 var $own_name = '<%= user.name %>';
8 8 var $muc_domain = '<%= "conference.#{environment.default_hostname}" %>';
9 9 var $bosh_service = '//<%= environment.default_hostname %>/http-bind';
10   - var $user_unavailable_error = '<%= _("<strong>ooops!</strong> The message could not be sent because the user is not online") %>';
  10 + var $user_unavailable_error = '<%= _("The user is not online now. He/She will receive these messages as soon as he/she gets online.") %>';
11 11 var $update_presence_status_every = <%= User.expires_chat_status_every.minutes %>;
12 12 var $presence = '<%= current_user.last_chat_status %>';
13 13 </script>
14 14  
15   -
16 15 <div id="chat-label">
  16 + <span id="unread-messages"></span>
17 17 <span class="right-arrow">&#9654;</span>
18 18 <span class="title"><%= _('Chat') %></span>
19 19 </div>
... ... @@ -98,10 +98,5 @@
98 98 </div>
99 99 </div>
100 100 </div>
101   -
102   - <div class="error-message">
103   - <span class='error'>%{text}</span>
104   - </div>
105   -
106 101 </div>
107 102 </div>
... ...
app/views/shared/profile_actions/xmpp_chat.html.erb 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<% label_name = profile.person? ? _('Open chat') : _('Join chat room') %>
  2 +<% display = profile.person? ? profile.friends.include?(user) : profile.members.include?(user) %>
  3 +
  4 +<% if display %>
  5 + <li>
  6 + <%= button(:chat, label_name , {}, :class => 'open-conversation', 'data-jid' => profile.jid) %>
  7 + </li>
  8 +<% end %>
... ...
app/views/tasks/_abuse_complaint_accept_details.html.erb
... ... @@ -2,7 +2,7 @@
2 2 <% task.abuse_reports.each do |abuse_report| %>
3 3 <div>
4 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 6 <% if !abuse_report.content.blank? %>
7 7 <button class="display-abuse-report-details" data-report="<%=abuse_report.id%>"><%=_('View details')%></button>
8 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,8 +2,26 @@
2 2  
3 3 <%= render :partial => 'task_icon', :locals => {:task => task} %>
4 4  
  5 + <% if !@view_only && profile.organization? && @responsible_candidates.present? %>
  6 + <div class="task_responsible">
  7 + <span class="label"><%= _('Assign to:') %></span>
  8 + <span>
  9 + <% change_responsible_url = url_for :action => :change_responsible, :controller => :tasks %>
  10 + <%= select_tag "tasks[#{task.id}][responsible]", options_from_collection_for_select(@responsible_candidates, :id, :name, task.responsible.present? ? task.responsible.id : nil), :include_blank => true, :onchange => "change_task_responsible(this);", 'data-old-responsible' => task.responsible.present? ? task.responsible.id : nil, 'data-task' => task.id, 'data-url' => change_responsible_url %>
  11 + </span>
  12 + </div>
  13 + <% end %>
  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 +
5 22 <div class="task_decisions">
6   - <%=
  23 + <% unless @view_only %>
  24 + <%=
7 25 labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.default_decision == 'accept',
8 26 :id => "decision-finish-#{task.id}",
9 27 :class => 'task_accept_radio',
... ... @@ -19,9 +37,12 @@
19 37 :class => 'task_skip_radio',
20 38 :disabled => task.skip_disabled?,
21 39 :task_id => "#{task.id}")
22   - %>
  40 + %>
  41 + <% end %>
23 42 </div><!-- class="task_decisions" -->
24 43  
  44 + <div class="task_date"><%= show_time(task.created_at) %></div>
  45 +
25 46 <%= render :partial => 'task_title', :locals => {:task => task} %>
26 47  
27 48 <div class="task_information">
... ...
app/views/tasks/index.html.erb
... ... @@ -21,58 +21,66 @@
21 21 </div>
22 22 <% end %>
23 23  
24   -<%= form_tag '#', :method => 'post' do %>
25   -
26   - <%= field_set_tag _('Filter'), :class => 'filter_fields' do %>
27   - <p>
28   - <%= labelled_select(_('Type of task')+': ', :filter_type, :first, :last, @filter_type, type_collection, {:id => 'filter-type'}) %>
29   - </p>
30   - <p>
31   - <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text-autocomplete',:value => @filter_text}) %>
32   - </p>
33   - <p>
34   - <%= submit_button(:search, _('Search')) %>
35   - </p>
  24 +<%= form_tag '#', :method => 'get' do %>
  25 + <%= field_set_tag _('Filter'), :class => 'filter_fields' do %>
  26 + <p>
  27 + <%= labelled_select(_('Type of task')+': ', :filter_type, :first, :last, @filter_type, type_collection, {:id => 'filter-type'}) %>
  28 + </p>
  29 + <p>
  30 + <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text',:value => @filter_text}) %>
  31 + </p>
  32 + <% if profile.organization? %>
  33 + <p>
  34 + <%= labelled_select(_('Assigned to')+': ', :filter_responsible, :id, :name, @filter_responsible, [OpenStruct.new(:name => _('All'), :id => nil), OpenStruct.new(:name => _('Unassigned'), :id => -1)] + @responsible_candidates, :class => 'filter_responsible') %>
  35 + </p>
36 36 <% end %>
  37 + <p>
  38 + <%= submit_button(:search, _('Search')) %>
  39 + </p>
  40 + <% end %>
37 41 <% end %>
  42 +
38 43 <% if @tasks.empty? %>
39 44 <p>
40 45 <em><%= _('No pending tasks for %s') % profile.name %></em>
41 46 </p>
42 47 <% else %>
43 48 <%= form_tag :action => 'close' do%>
44   - <% button_bar do %>
  49 + <% button_bar(:class => 'task-actions') do %>
45 50 <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
46 51 <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>
47 52 <%= submit_button :save, _("Apply!") %>
48 53 <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
49 54 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
50   - <% end %>
  55 + <% end unless @view_only %>
51 56  
52 57 <ul class='task-list'>
53   - <p>
54   - <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
55   - </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 %>
56 63  
57 64 <div class="task_boxes">
58   - <% @tasks.each do |task| %>
59   - <%= render :partial => 'task', :locals => { :task => task } %>
60   - <% end %>
  65 + <%= render :partial => 'task', :collection => @tasks %>
61 66 </div>
62   - <p>
63   - <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>
64   - </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 %>
65 73 </ul>
66 74  
67 75 <%= pagination_links(@tasks)%>
68 76  
69   - <% button_bar do %>
  77 + <% button_bar(:class => 'task-actions') do %>
70 78 <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
71 79 <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>
72 80 <%= submit_button :save, _("Apply!") %>
73 81 <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
74 82 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
75   - <% end %>
  83 + <% end unless @view_only %>
76 84 <% end %>
77 85 <% end %>
78 86 </p>
... ...
app/views/users/_users_list.html.erb
1   -<div class="environment-users-results-header">
2   - <div id='environment-users-filter-title'><%= users_filter_title(@filter) %></div>
  1 +<div class="environment-profiles-results-header">
  2 + <div id='environment-profiles-filter-title'><%= users_filter_title(@filter) %></div>
3 3 <%= filter_selector(@filter) %>
4 4 <div style="clear: both"></div>
5 5 </div>
... ...