Revision 1227
Added by Jean-Philippe Lang over 17 years ago
Activity enhancements:
- overall activity view and feed added, link is available on the project list (#423, #494)
- switch added on the project activity view to include subprojects (closes #530)
trunk/app/controllers/projects_controller.rb | ||
---|---|---|
24 | 24 |
menu_item :settings, :only => :settings |
25 | 25 |
menu_item :issues, :only => [:changelog] |
26 | 26 |
|
27 |
before_filter :find_project, :except => [ :index, :list, :add ] |
|
28 |
before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy ] |
|
27 |
before_filter :find_project, :except => [ :index, :list, :add, :activity ] |
|
28 |
before_filter :find_optional_project, :only => :activity |
|
29 |
before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy, :activity ] |
|
29 | 30 |
before_filter :require_admin, :only => [ :add, :archive, :unarchive, :destroy ] |
30 | 31 |
accept_key_auth :activity, :calendar |
31 | 32 |
|
... | ... | |
228 | 229 |
@date_from = @date_to - @days |
229 | 230 |
|
230 | 231 |
@event_types = %w(issues news files documents changesets wiki_pages messages) |
231 |
@event_types.delete('wiki_pages') unless @project.wiki |
|
232 |
@event_types.delete('changesets') unless @project.repository |
|
233 |
@event_types.delete('messages') unless @project.boards.any? |
|
234 |
# only show what the user is allowed to view |
|
235 |
@event_types = @event_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, @project)} |
|
236 |
|
|
232 |
if @project |
|
233 |
@event_types.delete('wiki_pages') unless @project.wiki |
|
234 |
@event_types.delete('changesets') unless @project.repository |
|
235 |
@event_types.delete('messages') unless @project.boards.any? |
|
236 |
# only show what the user is allowed to view |
|
237 |
@event_types = @event_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, @project)} |
|
238 |
@with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1') |
|
239 |
end |
|
237 | 240 |
@scope = @event_types.select {|t| params["show_#{t}"]} |
238 | 241 |
# default events if none is specified in parameters |
239 | 242 |
@scope = (@event_types - %w(wiki_pages messages))if @scope.empty? |
... | ... | |
241 | 244 |
@events = [] |
242 | 245 |
|
243 | 246 |
if @scope.include?('issues') |
244 |
@events += @project.issues.find(:all, :include => [:author, :tracker], :conditions => ["#{Issue.table_name}.created_on>=? and #{Issue.table_name}.created_on<=?", @date_from, @date_to] ) |
|
245 |
@events += @project.issues_status_changes(@date_from, @date_to) |
|
247 |
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_issues, :project => @project, :with_subprojects => @with_subprojects)) |
|
248 |
cond.add(["#{Issue.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to]) |
|
249 |
@events += Issue.find(:all, :include => [:project, :author, :tracker], :conditions => cond.conditions) |
|
250 |
|
|
251 |
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_issues, :project => @project, :with_subprojects => @with_subprojects)) |
|
252 |
cond.add(["#{Journal.table_name}.journalized_type = 'Issue' AND #{JournalDetail.table_name}.prop_key = 'status_id' AND #{Journal.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to]) |
|
253 |
@events += Journal.find(:all, :include => [{:issue => :project}, :details, :user], :conditions => cond.conditions) |
|
246 | 254 |
end |
247 | 255 |
|
248 | 256 |
if @scope.include?('news') |
249 |
@events += @project.news.find(:all, :conditions => ["#{News.table_name}.created_on>=? and #{News.table_name}.created_on<=?", @date_from, @date_to], :include => :author ) |
|
257 |
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_news, :project => @project, :with_subprojects => @with_subprojects)) |
|
258 |
cond.add(["#{News.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to]) |
|
259 |
@events += News.find(:all, :include => [:project, :author], :conditions => cond.conditions) |
|
250 | 260 |
end |
251 | 261 |
|
252 | 262 |
if @scope.include?('files') |
253 |
@events += Attachment.find(:all, :select => "#{Attachment.table_name}.*", :joins => "LEFT JOIN #{Version.table_name} ON #{Version.table_name}.id = #{Attachment.table_name}.container_id", :conditions => ["#{Attachment.table_name}.container_type='Version' and #{Version.table_name}.project_id=? and #{Attachment.table_name}.created_on>=? and #{Attachment.table_name}.created_on<=?", @project.id, @date_from, @date_to], :include => :author ) |
|
263 |
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_files, :project => @project, :with_subprojects => @with_subprojects)) |
|
264 |
cond.add(["#{Attachment.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to]) |
|
265 |
@events += Attachment.find(:all, :select => "#{Attachment.table_name}.*", |
|
266 |
:joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " + |
|
267 |
"LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id", |
|
268 |
:conditions => cond.conditions) |
|
254 | 269 |
end |
255 | 270 |
|
256 | 271 |
if @scope.include?('documents') |
257 |
@events += @project.documents.find(:all, :conditions => ["#{Document.table_name}.created_on>=? and #{Document.table_name}.created_on<=?", @date_from, @date_to] ) |
|
258 |
@events += Attachment.find(:all, :select => "attachments.*", :joins => "LEFT JOIN #{Document.table_name} ON #{Document.table_name}.id = #{Attachment.table_name}.container_id", :conditions => ["#{Attachment.table_name}.container_type='Document' and #{Document.table_name}.project_id=? and #{Attachment.table_name}.created_on>=? and #{Attachment.table_name}.created_on<=?", @project.id, @date_from, @date_to], :include => :author ) |
|
272 |
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_documents, :project => @project, :with_subprojects => @with_subprojects)) |
|
273 |
cond.add(["#{Document.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to]) |
|
274 |
@events += Document.find(:all, :include => :project, :conditions => cond.conditions) |
|
275 |
|
|
276 |
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_documents, :project => @project, :with_subprojects => @with_subprojects)) |
|
277 |
cond.add(["#{Attachment.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to]) |
|
278 |
@events += Attachment.find(:all, :select => "#{Attachment.table_name}.*", |
|
279 |
:joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " + |
|
280 |
"LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id", |
|
281 |
:conditions => cond.conditions) |
|
259 | 282 |
end |
260 | 283 |
|
261 | 284 |
if @scope.include?('wiki_pages') |
... | ... | |
264 | 287 |
"#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " + |
265 | 288 |
"#{WikiContent.versioned_table_name}.id" |
266 | 289 |
joins = "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " + |
267 |
"LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " |
|
268 |
conditions = ["#{Wiki.table_name}.project_id = ? AND #{WikiContent.versioned_table_name}.updated_on BETWEEN ? AND ?", |
|
269 |
@project.id, @date_from, @date_to] |
|
290 |
"LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " + |
|
291 |
"LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id" |
|
270 | 292 |
|
271 |
@events += WikiContent.versioned_class.find(:all, :select => select, :joins => joins, :conditions => conditions) |
|
293 |
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_wiki_pages, :project => @project, :with_subprojects => @with_subprojects)) |
|
294 |
cond.add(["#{WikiContent.versioned_table_name}.updated_on BETWEEN ? AND ?", @date_from, @date_to]) |
|
295 |
@events += WikiContent.versioned_class.find(:all, :select => select, :joins => joins, :conditions => cond.conditions) |
|
272 | 296 |
end |
273 | 297 |
|
274 | 298 |
if @scope.include?('changesets') |
275 |
@events += Changeset.find(:all, :include => :repository, :conditions => ["#{Repository.table_name}.project_id = ? AND #{Changeset.table_name}.committed_on BETWEEN ? AND ?", @project.id, @date_from, @date_to]) |
|
299 |
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_changesets, :project => @project, :with_subprojects => @with_subprojects)) |
|
300 |
cond.add(["#{Changeset.table_name}.committed_on BETWEEN ? AND ?", @date_from, @date_to]) |
|
301 |
@events += Changeset.find(:all, :include => {:repository => :project}, :conditions => cond.conditions) |
|
276 | 302 |
end |
277 | 303 |
|
278 | 304 |
if @scope.include?('messages') |
279 |
@events += Message.find(:all,
|
|
280 |
:include => [:board, :author],
|
|
281 |
:conditions => ["#{Board.table_name}.project_id=? AND #{Message.table_name}.created_on BETWEEN ? AND ?", @project.id, @date_from, @date_to])
|
|
305 |
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_messages, :project => @project, :with_subprojects => @with_subprojects))
|
|
306 |
cond.add(["#{Message.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
|
307 |
@events += Message.find(:all, :include => [{:board => :project}, :author], :conditions => cond.conditions)
|
|
282 | 308 |
end |
283 | 309 |
|
284 | 310 |
@events_by_day = @events.group_by(&:event_date) |
285 | 311 |
|
286 | 312 |
respond_to do |format| |
287 | 313 |
format.html { render :layout => false if request.xhr? } |
288 |
format.atom { render_feed(@events, :title => "#{@project.name}: #{l(:label_activity)}") }
|
|
314 |
format.atom { render_feed(@events, :title => "#{@project || Setting.app_title}: #{l(:label_activity)}") }
|
|
289 | 315 |
end |
290 | 316 |
end |
291 | 317 |
|
... | ... | |
381 | 407 |
render_404 |
382 | 408 |
end |
383 | 409 |
|
410 |
def find_optional_project |
|
411 |
return true unless params[:id] |
|
412 |
@project = Project.find(params[:id]) |
|
413 |
authorize |
|
414 |
rescue ActiveRecord::RecordNotFound |
|
415 |
render_404 |
|
416 |
end |
|
417 |
|
|
384 | 418 |
def retrieve_selected_tracker_ids(selectable_trackers) |
385 | 419 |
if ids = params[:tracker_ids] |
386 | 420 |
@selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s } |
trunk/app/models/attachment.rb | ||
---|---|---|
26 | 26 |
validates_length_of :disk_filename, :maximum => 255 |
27 | 27 |
|
28 | 28 |
acts_as_event :title => :filename, |
29 |
:description => :filename, |
|
30 | 29 |
:url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id}} |
31 | 30 |
|
32 | 31 |
cattr_accessor :storage_path |
trunk/app/models/changeset.rb | ||
---|---|---|
45 | 45 |
super |
46 | 46 |
end |
47 | 47 |
|
48 |
def project |
|
49 |
repository.project |
|
50 |
end |
|
51 |
|
|
48 | 52 |
def after_create |
49 | 53 |
scan_comment_for_issue_ids |
50 | 54 |
end |
trunk/app/models/project.rb | ||
---|---|---|
84 | 84 |
end |
85 | 85 |
end |
86 | 86 |
|
87 |
# Return all issues status changes for the project between the 2 given dates |
|
88 |
def issues_status_changes(from, to) |
|
89 |
Journal.find(:all, :include => [:issue, :details, :user], |
|
90 |
:conditions => ["#{Journal.table_name}.journalized_type = 'Issue'" + |
|
91 |
" AND #{Issue.table_name}.project_id = ?" + |
|
92 |
" AND #{JournalDetail.table_name}.prop_key = 'status_id'" + |
|
93 |
" AND #{Journal.table_name}.created_on BETWEEN ? AND ?", |
|
94 |
id, from, to+1]) |
|
95 |
end |
|
96 |
|
|
97 | 87 |
# returns latest created projects |
98 | 88 |
# non public projects will be returned only if user is a member of those |
99 | 89 |
def self.latest(user=nil, count=5) |
... | ... | |
110 | 100 |
end |
111 | 101 |
end |
112 | 102 |
|
113 |
def self.allowed_to_condition(user, permission) |
|
103 |
def self.allowed_to_condition(user, permission, options={})
|
|
114 | 104 |
statements = [] |
115 |
active_statement = "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}" |
|
105 |
base_statement = "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}" |
|
106 |
if options[:project] |
|
107 |
project_statement = "#{Project.table_name}.id = #{options[:project].id}" |
|
108 |
project_statement << " OR #{Project.table_name}.parent_id = #{options[:project].id}" if options[:with_subprojects] |
|
109 |
base_statement = "(#{project_statement}) AND (#{base_statement})" |
|
110 |
end |
|
116 | 111 |
if user.admin? |
117 | 112 |
# no restriction |
118 | 113 |
elsif user.logged? |
119 | 114 |
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}" if Role.non_member.allowed_to?(permission) |
120 | 115 |
allowed_project_ids = user.memberships.select {|m| m.role.allowed_to?(permission)}.collect {|m| m.project_id} |
121 | 116 |
statements << "#{Project.table_name}.id IN (#{allowed_project_ids.join(',')})" if allowed_project_ids.any? |
117 |
elsif Role.anonymous.allowed_to?(permission) |
|
118 |
# anonymous user allowed on public project |
|
119 |
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}" |
|
122 | 120 |
else |
123 |
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}" if Role.anonymous.allowed_to?(permission) |
|
121 |
# anonymous user is not authorized |
|
122 |
statements << "1=0" |
|
124 | 123 |
end |
125 |
statements.empty? ? active_statement : "(#{active_statement} AND (#{statements.join(' OR ')}))"
|
|
124 |
statements.empty? ? base_statement : "((#{base_statement}) AND (#{statements.join(' OR ')}))"
|
|
126 | 125 |
end |
127 | 126 |
|
128 | 127 |
def self.find(*args) |
trunk/app/models/wiki_content.rb | ||
---|---|---|
61 | 61 |
end |
62 | 62 |
end |
63 | 63 |
|
64 |
def project |
|
65 |
page.project |
|
66 |
end |
|
67 |
|
|
64 | 68 |
# Returns the previous version or nil |
65 | 69 |
def previous |
66 | 70 |
@previous ||= WikiContent::Version.find(:first, |
trunk/app/views/common/feed.atom.rxml | ||
---|---|---|
9 | 9 |
xml.generator(:uri => Redmine::Info.url, :version => Redmine::VERSION) { xml.text! Redmine::Info.versioned_name; } |
10 | 10 |
@items.each do |item| |
11 | 11 |
xml.entry do |
12 |
url = url_for(item.event_url(:only_path => false)) |
|
12 | 13 |
xml.title truncate(item.event_title, 100) |
13 |
xml.link "rel" => "alternate", "href" => url_for(item.event_url(:only_path => false))
|
|
14 |
xml.id url_for(item.event_url(:only_path => false))
|
|
14 |
xml.link "rel" => "alternate", "href" => url |
|
15 |
xml.id url |
|
15 | 16 |
xml.updated item.event_datetime.xmlschema |
16 | 17 |
author = item.event_author if item.respond_to?(:author) |
17 | 18 |
xml.author do |
trunk/app/views/projects/activity.rhtml | ||
---|---|---|
6 | 6 |
<dl> |
7 | 7 |
<% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%> |
8 | 8 |
<dt class="<%= e.class.name.downcase %>"><span class="time"><%= format_time(e.event_datetime, false) %></span> |
9 |
<%= link_to h(truncate(e.event_title, 100)), e.event_url %></dt> |
|
9 |
<%= content_tag('span', h(e.project), :class => 'project') if @project.nil? || @project != e.project %> <%= link_to h(truncate(e.event_title, 100)), e.event_url %></dt>
|
|
10 | 10 |
<dd><% unless e.event_description.blank? -%> |
11 | 11 |
<span class="description"><%= format_activity_description(e.event_description) %></span><br /> |
12 | 12 |
<% end %> |
... | ... | |
35 | 35 |
</p> |
36 | 36 |
|
37 | 37 |
<% content_for :header_tags do %> |
38 |
<%= auto_discovery_link_tag(:atom, params.merge(:format => 'atom', :year => nil, :month => nil, :key => User.current.rss_key).delete_if{|k,v|k=="commit"}) %>
|
|
38 |
<%= auto_discovery_link_tag(:atom, params.merge(:format => 'atom', :year => nil, :month => nil, :key => User.current.rss_key)) %> |
|
39 | 39 |
<% end %> |
40 | 40 |
|
41 | 41 |
<% content_for :sidebar do %> |
42 |
<% form_tag do %> |
|
42 |
<% form_tag({}, :method => :get) do %>
|
|
43 | 43 |
<h3><%= l(:label_activity) %></h3> |
44 | 44 |
<p><% @event_types.each do |t| %> |
45 | 45 |
<label><%= check_box_tag "show_#{t}", 1, @scope.include?(t) %> <%= l("label_#{t.singularize}_plural")%></label><br /> |
46 | 46 |
<% end %></p> |
47 |
<p><%= submit_tag l(:button_apply), :class => 'button-small' %></p> |
|
47 |
<% if @project && @project.active_children.any? %> |
|
48 |
<p><label><%= check_box_tag 'with_subprojects', 1, @with_subprojects %> <%=l(:label_subproject_plural)%></label></p> |
|
49 |
<%= hidden_field_tag 'with_subprojects', 0 %> |
|
48 | 50 |
<% end %> |
51 |
<p><%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %></p> |
|
49 | 52 |
<% end %> |
53 |
<% end %> |
|
50 | 54 |
|
51 | 55 |
<% html_title(l(:label_activity)) -%> |
trunk/app/views/projects/list.rhtml | ||
---|---|---|
1 |
<div class="contextual"> |
|
2 |
<%= link_to l(:label_issue_view_all), { :controller => 'issues' } %> | |
|
3 |
<%= link_to l(:label_overall_activity), { :controller => 'projects', :action => 'activity' }%> |
|
4 |
</div> |
|
5 |
|
|
1 | 6 |
<h2><%=l(:label_project_plural)%></h2> |
2 | 7 |
|
3 | 8 |
<% @project_tree.keys.sort.each do |project| %> |
trunk/app/views/welcome/index.rhtml | ||
---|---|---|
26 | 26 |
</div> |
27 | 27 |
|
28 | 28 |
<% content_for :header_tags do %> |
29 |
<%= auto_discovery_link_tag(:atom, {:controller => 'news', :action => 'index', :key => User.current.rss_key, :format => 'atom'}, {:title => l(:label_news_latest)}) %> |
|
29 |
<%= auto_discovery_link_tag(:atom, {:controller => 'news', :action => 'index', :key => User.current.rss_key, :format => 'atom'}, |
|
30 |
:title => "#{Setting.app_title}: #{l(:label_news_latest)}") %> |
|
31 |
<%= auto_discovery_link_tag(:atom, {:controller => 'projects', :action => 'activity', :key => User.current.rss_key, :format => 'atom'}, |
|
32 |
:title => "#{Setting.app_title}: #{l(:label_activity)}") %> |
|
30 | 33 |
<% end %> |
trunk/lang/bg.yml | ||
---|---|---|
613 | 613 |
label_reverse_chronological_order: In reverse chronological order |
614 | 614 |
label_preferences: Preferences |
615 | 615 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
616 |
label_overall_activity: Overall activity |
trunk/lang/cs.yml | ||
---|---|---|
613 | 613 |
label_reverse_chronological_order: In reverse chronological order |
614 | 614 |
label_preferences: Preferences |
615 | 615 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
616 |
label_overall_activity: Overall activity |
trunk/lang/da.yml | ||
---|---|---|
615 | 615 |
text_reassign_time_entries: 'Reassign reported hours to this issue:' |
616 | 616 |
label_reverse_chronological_order: In reverse chronological order |
617 | 617 |
label_preferences: Preferences |
618 |
label_overall_activity: Overall activity |
trunk/lang/de.yml | ||
---|---|---|
614 | 614 |
label_reverse_chronological_order: In reverse chronological order |
615 | 615 |
label_preferences: Preferences |
616 | 616 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
617 |
label_overall_activity: Overall activity |
trunk/lang/en.yml | ||
---|---|---|
280 | 280 |
label_last_updates_plural: %d last updated |
281 | 281 |
label_registered_on: Registered on |
282 | 282 |
label_activity: Activity |
283 |
label_overall_activity: Overall activity |
|
283 | 284 |
label_new: New |
284 | 285 |
label_logged_as: Logged as |
285 | 286 |
label_environment: Environment |
trunk/lang/es.yml | ||
---|---|---|
616 | 616 |
label_reverse_chronological_order: In reverse chronological order |
617 | 617 |
label_preferences: Preferences |
618 | 618 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
619 |
label_overall_activity: Overall activity |
trunk/lang/fi.yml | ||
---|---|---|
620 | 620 |
field_comments_sorting: Display comments |
621 | 621 |
label_reverse_chronological_order: In reverse chronological order |
622 | 622 |
label_preferences: Preferences |
623 |
label_overall_activity: Overall activity |
trunk/lang/fr.yml | ||
---|---|---|
165 | 165 |
field_subproject: Sous-projet |
166 | 166 |
field_hours: Heures |
167 | 167 |
field_activity: Activité |
168 |
label_overall_activity: Activité globale |
|
168 | 169 |
field_spent_on: Date |
169 | 170 |
field_identifier: Identifiant |
170 | 171 |
field_is_filter: Utilisé comme filtre |
... | ... | |
452 | 453 |
label_start_to_end: début à fin |
453 | 454 |
label_stay_logged_in: Rester connecté |
454 | 455 |
label_disabled: désactivé |
455 |
label_show_completed_versions: Voire les versions passées
|
|
456 |
label_show_completed_versions: Voir les versions passées |
|
456 | 457 |
label_me: moi |
457 | 458 |
label_board: Forum |
458 | 459 |
label_board_new: Nouveau forum |
trunk/lang/he.yml | ||
---|---|---|
613 | 613 |
label_reverse_chronological_order: In reverse chronological order |
614 | 614 |
label_preferences: Preferences |
615 | 615 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
616 |
label_overall_activity: Overall activity |
trunk/lang/it.yml | ||
---|---|---|
613 | 613 |
label_reverse_chronological_order: In reverse chronological order |
614 | 614 |
label_preferences: Preferences |
615 | 615 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
616 |
label_overall_activity: Overall activity |
trunk/lang/ja.yml | ||
---|---|---|
614 | 614 |
label_reverse_chronological_order: In reverse chronological order |
615 | 615 |
label_preferences: Preferences |
616 | 616 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
617 |
label_overall_activity: Overall activity |
trunk/lang/ko.yml | ||
---|---|---|
613 | 613 |
label_reverse_chronological_order: In reverse chronological order |
614 | 614 |
label_preferences: Preferences |
615 | 615 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
616 |
label_overall_activity: Overall activity |
trunk/lang/lt.yml | ||
---|---|---|
614 | 614 |
label_reverse_chronological_order: In reverse chronological order |
615 | 615 |
label_preferences: Preferences |
616 | 616 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
617 |
label_overall_activity: Overall activity |
trunk/lang/nl.yml | ||
---|---|---|
614 | 614 |
label_reverse_chronological_order: In reverse chronological order |
615 | 615 |
label_preferences: Preferences |
616 | 616 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
617 |
label_overall_activity: Overall activity |
trunk/lang/pl.yml | ||
---|---|---|
613 | 613 |
field_comments_sorting: Display comments |
614 | 614 |
label_reverse_chronological_order: In reverse chronological order |
615 | 615 |
label_preferences: Preferences |
616 |
label_overall_activity: Overall activity |
trunk/lang/pt-br.yml | ||
---|---|---|
613 | 613 |
label_reverse_chronological_order: In reverse chronological order |
614 | 614 |
label_preferences: Preferences |
615 | 615 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
616 |
label_overall_activity: Overall activity |
trunk/lang/pt.yml | ||
---|---|---|
613 | 613 |
label_reverse_chronological_order: In reverse chronological order |
614 | 614 |
label_preferences: Preferences |
615 | 615 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
616 |
label_overall_activity: Overall activity |
trunk/lang/ro.yml | ||
---|---|---|
613 | 613 |
label_reverse_chronological_order: In reverse chronological order |
614 | 614 |
label_preferences: Preferences |
615 | 615 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
616 |
label_overall_activity: Overall activity |
trunk/lang/ru.yml | ||
---|---|---|
617 | 617 |
label_reverse_chronological_order: In reverse chronological order |
618 | 618 |
label_preferences: Preferences |
619 | 619 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
620 |
label_overall_activity: Overall activity |
trunk/lang/sr.yml | ||
---|---|---|
614 | 614 |
label_reverse_chronological_order: In reverse chronological order |
615 | 615 |
label_preferences: Preferences |
616 | 616 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
617 |
label_overall_activity: Overall activity |
trunk/lang/sv.yml | ||
---|---|---|
614 | 614 |
label_reverse_chronological_order: In reverse chronological order |
615 | 615 |
label_preferences: Preferences |
616 | 616 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
617 |
label_overall_activity: Overall activity |
trunk/lang/uk.yml | ||
---|---|---|
615 | 615 |
label_reverse_chronological_order: In reverse chronological order |
616 | 616 |
label_preferences: Preferences |
617 | 617 |
setting_display_subprojects_issues: Display subprojects issues on main projects by default |
618 |
label_overall_activity: Overall activity |
trunk/lang/zh-tw.yml | ||
---|---|---|
614 | 614 |
enumeration_issue_priorities: 項目優先權 |
615 | 615 |
enumeration_doc_categories: 文件分類 |
616 | 616 |
enumeration_activities: 活動 (time tracking) |
617 |
label_overall_activity: Overall activity |
trunk/lang/zh.yml | ||
---|---|---|
614 | 614 |
enumeration_issue_priorities: 问题优先级 |
615 | 615 |
enumeration_doc_categories: 文档类别 |
616 | 616 |
enumeration_activities: 活动(时间跟踪) |
617 |
label_overall_activity: Overall activity |
trunk/lib/ar_condition.rb | ||
---|---|---|
20 | 20 |
|
21 | 21 |
def initialize(condition=nil) |
22 | 22 |
@conditions = ['1=1'] |
23 |
@conditions.add(condition) if condition
|
|
23 |
add(condition) if condition |
|
24 | 24 |
end |
25 | 25 |
|
26 | 26 |
def add(condition) |
trunk/public/stylesheets/application.css | ||
---|---|---|
169 | 169 |
div#activity dt { margin-bottom: 1px; } |
170 | 170 |
div#activity dt .time { color: #777; font-size: 80%; } |
171 | 171 |
div#activity dd .description { font-style: italic; } |
172 |
div#activity span.project:after { content: " -"; } |
|
172 | 173 |
|
173 | 174 |
div#roadmap fieldset.related-issues { margin-bottom: 1em; } |
174 | 175 |
div#roadmap fieldset.related-issues ul { margin-top: 0.3em; margin-bottom: 0.3em; } |
trunk/test/fixtures/issues.yml | ||
---|---|---|
44 | 44 |
start_date: <%= 1.day.from_now.to_date.to_s(:db) %> |
45 | 45 |
due_date: <%= 40.day.ago.to_date.to_s(:db) %> |
46 | 46 |
issues_004: |
47 |
created_on: 2006-07-19 21:07:27 +02:00
|
|
47 |
created_on: <%= 5.days.ago.to_date.to_s(:db) %>
|
|
48 | 48 |
project_id: 2 |
49 |
updated_on: 2006-07-19 21:07:27 +02:00
|
|
49 |
updated_on: <%= 2.days.ago.to_date.to_s(:db) %>
|
|
50 | 50 |
priority_id: 4 |
51 | 51 |
subject: Issue on project 2 |
52 | 52 |
id: 4 |
... | ... | |
57 | 57 |
assigned_to_id: |
58 | 58 |
author_id: 2 |
59 | 59 |
status_id: 1 |
60 |
issues_005: |
|
61 |
created_on: <%= 5.days.ago.to_date.to_s(:db) %> |
|
62 |
project_id: 3 |
|
63 |
updated_on: <%= 2.days.ago.to_date.to_s(:db) %> |
|
64 |
priority_id: 4 |
|
65 |
subject: Subproject issue |
|
66 |
id: 5 |
|
67 |
fixed_version_id: |
|
68 |
category_id: |
|
69 |
description: This is an issue on a cookbook subproject |
|
70 |
tracker_id: 1 |
|
71 |
assigned_to_id: |
|
72 |
author_id: 2 |
|
73 |
status_id: 1 |
|
60 | 74 |
|
trunk/test/fixtures/messages.yml | ||
---|---|---|
45 | 45 |
parent_id: |
46 | 46 |
board_id: 1 |
47 | 47 |
messages_005: |
48 |
created_on: 2007-09-12 17:18:00 +02:00
|
|
49 |
updated_on: 2007-09-12 17:18:00 +02:00
|
|
48 |
created_on: <%= 3.days.ago.to_date.to_s(:db) %>
|
|
49 |
updated_on: <%= 3.days.ago.to_date.to_s(:db) %>
|
|
50 | 50 |
subject: 'RE: post 2' |
51 | 51 |
id: 5 |
52 | 52 |
replies_count: 0 |
trunk/test/functional/projects_controller_test.rb | ||
---|---|---|
22 | 22 |
class ProjectsController; def rescue_action(e) raise e end; end |
23 | 23 |
|
24 | 24 |
class ProjectsControllerTest < Test::Unit::TestCase |
25 |
fixtures :projects, :versions, :users, :roles, :members, :issues, :journals, :journal_details, :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations |
|
25 |
fixtures :projects, :versions, :users, :roles, :members, :issues, :journals, :journal_details, |
|
26 |
:trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages |
|
26 | 27 |
|
27 | 28 |
def setup |
28 | 29 |
@controller = ProjectsController.new |
... | ... | |
129 | 130 |
assert assigns(:versions).include?(Version.find(1)) |
130 | 131 |
end |
131 | 132 |
|
132 |
def test_activity |
|
133 |
get :activity, :id => 1 |
|
133 |
def test_project_activity
|
|
134 |
get :activity, :id => 1, :with_subprojects => 0
|
|
134 | 135 |
assert_response :success |
135 | 136 |
assert_template 'activity' |
136 | 137 |
assert_not_nil assigns(:events_by_day) |
138 |
assert_not_nil assigns(:events) |
|
139 |
|
|
140 |
# subproject issue not included by default |
|
141 |
assert !assigns(:events).include?(Issue.find(5)) |
|
137 | 142 |
|
138 | 143 |
assert_tag :tag => "h3", |
139 | 144 |
:content => /#{2.days.ago.to_date.day}/, |
... | ... | |
163 | 168 |
} |
164 | 169 |
end |
165 | 170 |
|
171 |
def test_activity_with_subprojects |
|
172 |
get :activity, :id => 1, :with_subprojects => 1 |
|
173 |
assert_response :success |
|
174 |
assert_template 'activity' |
|
175 |
assert_not_nil assigns(:events) |
|
176 |
|
|
177 |
assert assigns(:events).include?(Issue.find(1)) |
|
178 |
assert !assigns(:events).include?(Issue.find(4)) |
|
179 |
# subproject issue |
|
180 |
assert assigns(:events).include?(Issue.find(5)) |
|
181 |
end |
|
182 |
|
|
183 |
def test_global_activity_anonymous |
|
184 |
get :activity |
|
185 |
assert_response :success |
|
186 |
assert_template 'activity' |
|
187 |
assert_not_nil assigns(:events) |
|
188 |
|
|
189 |
assert assigns(:events).include?(Issue.find(1)) |
|
190 |
# Issue of a private project |
|
191 |
assert !assigns(:events).include?(Issue.find(4)) |
|
192 |
end |
|
193 |
|
|
194 |
def test_global_activity_logged_user |
|
195 |
@request.session[:user_id] = 2 # manager |
|
196 |
get :activity |
|
197 |
assert_response :success |
|
198 |
assert_template 'activity' |
|
199 |
assert_not_nil assigns(:events) |
|
200 |
|
|
201 |
assert assigns(:events).include?(Issue.find(1)) |
|
202 |
# Issue of a private project the user belongs to |
|
203 |
assert assigns(:events).include?(Issue.find(4)) |
|
204 |
end |
|
205 |
|
|
206 |
|
|
207 |
def test_global_activity_with_all_types |
|
208 |
get :activity, :show_issues => 1, :show_news => 1, :show_files => 1, :show_documents => 1, :show_changesets => 1, :show_wiki_pages => 1, :show_messages => 1 |
|
209 |
assert_response :success |
|
210 |
assert_template 'activity' |
|
211 |
assert_not_nil assigns(:events) |
|
212 |
|
|
213 |
assert assigns(:events).include?(Issue.find(1)) |
|
214 |
assert !assigns(:events).include?(Issue.find(4)) |
|
215 |
assert assigns(:events).include?(Message.find(5)) |
|
216 |
end |
|
217 |
|
|
166 | 218 |
def test_calendar |
167 | 219 |
get :calendar, :id => 1 |
168 | 220 |
assert_response :success |
trunk/test/unit/project_test.rb | ||
---|---|---|
126 | 126 |
assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id) |
127 | 127 |
assert_equal [2, 3], child.rolled_up_trackers.collect(&:id) |
128 | 128 |
end |
129 |
|
|
130 |
def test_issues_status_changes |
|
131 |
journals = @ecookbook.issues_status_changes 3.days.ago.to_date, Date.today |
|
132 |
assert_equal 1, journals.size |
|
133 |
assert_kind_of Journal, journals.first |
|
134 |
|
|
135 |
journals = @ecookbook.issues_status_changes 30.days.ago.to_date, 10.days.ago.to_date |
|
136 |
assert_equal 0, journals.size |
|
137 |
end |
|
138 | 129 |
end |
Also available in: Unified diff