Feature #465 » veersion_inheritance.patch
| app/controllers/issues_controller.rb Sun Jun 15 14:27:25 2008 +0200 → app/controllers/issues_controller.rb Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 20 | 20 |
menu_item :new_issue, :only => :new |
| 21 | 21 |
|
| 22 | 22 |
before_filter :find_issue, :only => [:show, :edit, :destroy_attachment] |
| 23 |
before_filter :check_issue_perms, :only => [:show, :edit] |
|
| 23 | 24 |
before_filter :find_issues, :only => [:bulk_edit, :move, :destroy] |
| 24 | 25 |
before_filter :find_project, :only => [:new, :update_form, :preview] |
| 25 | 26 |
before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu] |
| ... | ... | |
| 28 | 29 | |
| 29 | 30 |
helper :journals |
| 30 | 31 |
helper :projects |
| 31 |
include ProjectsHelper
|
|
| 32 |
include ProjectsHelper |
|
| 32 | 33 |
helper :custom_fields |
| 33 | 34 |
include CustomFieldsHelper |
| 34 | 35 |
helper :ifpdf |
| ... | ... | |
| 63 | 64 |
:conditions => @query.statement, |
| 64 | 65 |
:limit => limit, |
| 65 | 66 |
:offset => @issue_pages.current.offset |
| 67 |
@issues.map!{ |issue| issue_without_hidden_fields(issue) } # don't show forbidden fields
|
|
| 66 | 68 |
respond_to do |format| |
| 67 | 69 |
format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
|
| 68 | 70 |
format.atom { render_feed(@issues, :title => l(:label_issue_plural)) }
|
| ... | ... | |
| 100 | 102 |
@journals.reverse! if User.current.wants_comments_in_reverse_order? |
| 101 | 103 |
@allowed_statuses = @issue.new_statuses_allowed_to(User.current) |
| 102 | 104 |
@edit_allowed = User.current.allowed_to?(:edit_issues, @project) |
| 105 |
@issue = issue_without_hidden_fields(@issue) |
|
| 106 |
@journals = journals_without_hidden_entries(@journals) |
|
| 103 | 107 |
@activities = Enumeration::get_values('ACTI')
|
| 104 | 108 |
@priorities = Enumeration::get_values('IPRI')
|
| 105 | 109 |
@time_entry = TimeEntry.new |
| ... | ... | |
| 388 | 392 |
render_404 |
| 389 | 393 |
end |
| 390 | 394 |
|
| 395 |
|
|
| 396 | ||
| 397 |
def issue_fixed_version_allowed?(issue) |
|
| 398 |
((not issue.fixed_version) || |
|
| 399 |
(User.current.allowed_to?(:view_issues, |
|
| 400 |
issue.fixed_version.project))) |
|
| 401 |
end |
|
| 402 | ||
| 403 |
def check_issue_perms |
|
| 404 |
@forbidden_fixed_version = (not issue_fixed_version_allowed?(@issue)) |
|
| 405 |
end |
|
| 406 | ||
| 407 |
## Filter journals to remove non allowed entries. This assumes there |
|
| 408 |
## is only 1 parent, so it won't work with more depth. We want here |
|
| 409 |
## to handle the _specific case_ of a user 'Joe' browsing 'Project |
|
| 410 |
## B' issues. 'Project B' is a subproject of 'Project A' and |
|
| 411 |
## inherits its versions. Joe can't see 'Project A, but issue |
|
| 412 |
## fixed_versions has been set at some point to a version belonging |
|
| 413 |
## to 'Project A', by an other member of 'Project B'. Joe should not |
|
| 414 |
## see this sensitive information. |
|
| 415 |
def journals_without_hidden_entries(journals) |
|
| 416 |
unless (journals.empty? || (not @project.parent_id) || |
|
| 417 |
(@project.parent_id && User.current.allowed_to?(:view_issues, @project.parent))) |
|
| 418 |
journals = journals.dup |
|
| 419 |
# we kill totally the journal entry when some of its elements are forbidden |
|
| 420 |
journals.delete_if do |j| |
|
| 421 |
j.details.map{ |d| (d.property == 'attr' &&
|
|
| 422 |
d.prop_key == 'fixed_version_id' && |
|
| 423 |
((d.old_value && |
|
| 424 |
(@project.parent_id == Version.find(d.old_value.to_i).project_id)) || |
|
| 425 |
(d.value && |
|
| 426 |
(@project.parent_id == Version.find(d.value.to_i).project_id))) |
|
| 427 |
) }.include?(true) |
|
| 428 |
end |
|
| 429 |
end |
|
| 430 |
journals |
|
| 431 |
end |
|
| 432 | ||
| 433 |
## Filter issue to remove non allowed fields. For more information, |
|
| 434 |
## see documentation of journals_without_hidden_entries |
|
| 435 |
def issue_without_hidden_fields(issue) |
|
| 436 |
unless issue_fixed_version_allowed?(issue) |
|
| 437 |
issue = issue.dup |
|
| 438 |
issue.fixed_version = nil |
|
| 439 |
end |
|
| 440 |
issue |
|
| 441 |
end |
|
| 442 | ||
| 391 | 443 |
# Retrieve query from session or build a new query |
| 392 | 444 |
def retrieve_query |
| 393 | 445 |
if !params[:query_id].blank? |
| app/controllers/projects_controller.rb Sun Jun 15 14:27:25 2008 +0200 → app/controllers/projects_controller.rb Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 195 | 195 | |
| 196 | 196 |
def add_file |
| 197 | 197 |
if request.post? |
| 198 |
@version = @project.versions.find_by_id(params[:version_id]) |
|
| 198 |
@version = @project.related_versions.find_by_id(params[:version_id])
|
|
| 199 | 199 |
attachments = attach_files(@version, params[:attachments]) |
| 200 | 200 |
Mailer.deliver_attachments_added(attachments) if !attachments.empty? && Setting.notified_events.include?('file_added')
|
| 201 | 201 |
redirect_to :controller => 'projects', :action => 'list_files', :id => @project |
| 202 | 202 |
end |
| 203 |
@versions = @project.versions.sort |
|
| 203 |
@versions = @project.related_versions.sort
|
|
| 204 | 204 |
end |
| 205 | 205 |
|
| 206 | 206 |
def list_files |
| 207 | 207 |
sort_init "#{Attachment.table_name}.filename", "asc"
|
| 208 | 208 |
sort_update |
| 209 |
@versions = @project.versions.find(:all, :include => :attachments, :order => sort_clause).sort.reverse |
|
| 209 |
@versions = @project.related_versions.find(:all, :include => :attachments, :order => sort_clause).sort.reverse
|
|
| 210 | 210 |
render :layout => !request.xhr? |
| 211 | 211 |
end |
| 212 | 212 |
|
| ... | ... | |
| 214 | 214 |
def changelog |
| 215 | 215 |
@trackers = @project.trackers.find(:all, :conditions => ["is_in_chlog=?", true], :order => 'position') |
| 216 | 216 |
retrieve_selected_tracker_ids(@trackers) |
| 217 |
@versions = @project.versions.sort |
|
| 217 |
@versions = @project.related_versions.sort
|
|
| 218 | 218 |
end |
| 219 | 219 | |
| 220 | 220 |
def roadmap |
| 221 | 221 |
@trackers = @project.trackers.find(:all, :conditions => ["is_in_roadmap=?", true]) |
| 222 | 222 |
retrieve_selected_tracker_ids(@trackers) |
| 223 |
@versions = @project.versions.sort
|
|
| 224 |
@versions = @versions.select {|v| !v.completed? } unless params[:completed]
|
|
| 223 |
# retrieve_related_versions could be integrated right here.
|
|
| 224 |
@versions = retrieve_related_versions
|
|
| 225 | 225 |
end |
| 226 | 226 |
|
| 227 | 227 |
def activity |
| ... | ... | |
| 342 | 342 |
:conditions => ["((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?)) AND #{Issue.table_name}.tracker_id IN (#{@selected_tracker_ids.join(',')})", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt]
|
| 343 | 343 |
) unless @selected_tracker_ids.empty? |
| 344 | 344 |
events += Version.find(:all, :include => :project, |
| 345 |
:conditions => ["effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt])
|
|
| 345 |
:conditions => { :effective_date => @calendar.startdt..@calendar.enddt})
|
|
| 346 | 346 |
end |
| 347 |
# add parent versions if relevant |
|
| 348 |
events += @project.related_versions.select{ |v| ((v.project_id == @project.parent_id) &&
|
|
| 349 |
v.effective_date) } |
|
| 350 |
|
|
| 347 | 351 |
@calendar.events = events |
| 348 | 352 |
|
| 349 | 353 |
render :layout => false if request.xhr? |
| ... | ... | |
| 390 | 394 |
@events += Version.find(:all, :include => :project, |
| 391 | 395 |
:conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to]) |
| 392 | 396 |
end |
| 397 |
|
|
| 398 |
# add parent versions if relevant |
|
| 399 |
@events += @project.related_versions.select{ |v| ((v.project_id == @project.parent_id) &&
|
|
| 400 |
v.effective_date) } |
|
| 401 |
|
|
| 393 | 402 |
@events.sort! {|x,y| x.start_date <=> y.start_date }
|
| 394 | 403 |
|
| 395 | 404 |
if params[:format]=='pdf' |
| ... | ... | |
| 423 | 432 |
render_404 |
| 424 | 433 |
end |
| 425 | 434 | |
| 435 |
def retrieve_related_versions |
|
| 436 |
related_versions=@project.related_versions |
|
| 437 |
# should this test be moved to projects_helper.rb : version_visible_issues ? |
|
| 438 |
params[:completed] ? related_versions : related_versions.select {|v| !v.completed? }
|
|
| 439 |
end |
|
| 440 | ||
| 426 | 441 |
def retrieve_selected_tracker_ids(selectable_trackers) |
| 427 | 442 |
if ids = params[:tracker_ids] |
| 428 | 443 |
@selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s }
|
| app/controllers/reports_controller.rb Sun Jun 15 14:27:25 2008 +0200 → app/controllers/reports_controller.rb Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 32 | 32 |
render :template => "reports/issue_report_details" |
| 33 | 33 |
when "version" |
| 34 | 34 |
@field = "fixed_version_id" |
| 35 |
@rows = @project.versions.sort |
|
| 35 |
@rows = @project.related_versions.sort
|
|
| 36 | 36 |
@data = issues_by_version |
| 37 | 37 |
@report_title = l(:field_version) |
| 38 | 38 |
render :template => "reports/issue_report_details" |
| ... | ... | |
| 68 | 68 |
render :template => "reports/issue_report_details" |
| 69 | 69 |
else |
| 70 | 70 |
@trackers = @project.trackers |
| 71 |
@versions = @project.versions.sort |
|
| 71 |
@versions = @project.related_versions.sort
|
|
| 72 | 72 |
@priorities = Enumeration::get_values('IPRI')
|
| 73 | 73 |
@categories = @project.issue_categories |
| 74 | 74 |
@assignees = @project.members.collect { |m| m.user }
|
| app/controllers/versions_controller.rb Sun Jun 15 14:27:25 2008 +0200 → app/controllers/versions_controller.rb Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 20 | 20 |
menu_item :roadmap |
| 21 | 21 |
before_filter :find_project, :authorize |
| 22 | 22 | |
| 23 |
helper :projects |
|
| 24 |
include ProjectsHelper |
|
| 25 | ||
| 23 | 26 |
def show |
| 27 |
@issues = version_visible_issues(@version,@project,@project.tracker_ids) |
|
| 24 | 28 |
end |
| 25 | 29 |
|
| 26 | 30 |
def edit |
| app/helpers/projects_helper.rb Sun Jun 15 14:27:25 2008 +0200 → app/helpers/projects_helper.rb Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 46 | 46 |
tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
|
| 47 | 47 |
end |
| 48 | 48 |
|
| 49 |
## return an array of the issues attached to version that a user should see |
|
| 50 |
## As a convenience, allow limitation by trackers with Array of tracker_ids |
|
| 51 |
def version_visible_issues(version,project,tracker_ids=[],user=User.current) |
|
| 52 |
# Returns void when user can not see issues or if tracker_ids is void |
|
| 53 |
return [] if ((not user.allowed_to?(:view_issues, |
|
| 54 |
version.project)) or |
|
| 55 |
tracker_ids.empty?) |
|
| 56 |
# user can see project issues, carry on, retrieve them ... |
|
| 57 |
issues = version. |
|
| 58 |
fixed_issues.find(:all, |
|
| 59 |
:include => [:status, :tracker], |
|
| 60 |
:conditions => ["tracker_id in (#{tracker_ids.join(',')})"],
|
|
| 61 |
:order => "#{Tracker.table_name}.position, #{Issue.table_name}.id")
|
|
| 62 |
# Only keep issues from self, parent or children, |
|
| 63 |
related_projects=[project.id].concat(project.child_ids) # project and children |
|
| 64 |
related_projects.push project.parent.id if project.parent # parent if relevant |
|
| 65 |
related_projects = related_projects.select{|x| user.allowed_to?(:view_issues, Project.find(x))}
|
|
| 66 |
# now only keep related issues. (issues from brother projects are discarded) |
|
| 67 |
issues.select {|x| related_projects.include?(x.project.id) }
|
|
| 68 |
end |
|
| 69 | ||
| 49 | 70 |
# Generates a gantt image |
| 50 | 71 |
# Only defined if RMagick is avalaible |
| 51 | 72 |
def gantt_image(events, date_from, months, zoom) |
| app/models/project.rb Sun Jun 15 14:27:25 2008 +0200 → app/models/project.rb Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 237 | 237 |
end |
| 238 | 238 |
end |
| 239 | 239 | |
| 240 |
## Return versions attached to self, and to parent if relevant. |
|
| 241 |
## Sorting is done in the SQL request to take advantage of cache |
|
| 242 |
def related_versions(user=User.current) |
|
| 243 |
Version.find(:all, |
|
| 244 |
:conditions => {:project_id => if self.parent &&
|
|
| 245 |
user.allowed_to?(:view_issues, |
|
| 246 |
self.parent) then |
|
| 247 |
[self.id, self.parent_id] |
|
| 248 |
else [self.id]; end}, |
|
| 249 |
:order => "effective_date ASC, name ASC ") |
|
| 250 |
end |
|
| 251 | ||
| 240 | 252 |
protected |
| 241 | 253 |
def validate |
| 242 | 254 |
errors.add(parent_id, " must be a root project") if parent and parent.parent |
| app/models/query.rb Sun Jun 15 14:27:25 2008 +0200 → app/models/query.rb Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 168 | 168 |
if project |
| 169 | 169 |
# project specific filters |
| 170 | 170 |
@available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } }
|
| 171 |
@available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.sort.collect{|s| [s.name, s.id.to_s] } }
|
|
| 171 |
@available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.related_versions.sort.collect{|s| [s.name, s.id.to_s] } }
|
|
| 172 | 172 |
unless @project.active_children.empty? |
| 173 | 173 |
@available_filters["subproject_id"] = { :type => :list_subprojects, :order => 13, :values => @project.active_children.collect{|s| [s.name, s.id.to_s] } }
|
| 174 | 174 |
end |
| app/views/issues/_form.rhtml Sun Jun 15 14:27:25 2008 +0200 → app/views/issues/_form.rhtml Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 29 | 29 |
l(:label_issue_category_new), 'category[name]', |
| 30 | 30 |
{:controller => 'projects', :action => 'add_issue_category', :id => @project},
|
| 31 | 31 |
:class => 'small', :tabindex => 199) if authorize_for('projects', 'add_issue_category') %></p>
|
| 32 |
<%= content_tag('p', f.select(:fixed_version_id,
|
|
| 33 |
(@project.versions.sort.collect {|v| [v.name, v.id]}),
|
|
| 34 |
{ :include_blank => true })) unless @project.versions.empty? %>
|
|
| 32 |
<%= unless (@project.related_versions.empty? || @forbidden_fixed_version) then |
|
| 33 |
content_tag('p', f.select(:fixed_version_id,
|
|
| 34 |
(@project.related_versions.sort.collect {|v| [v.name, v.id]}),
|
|
| 35 |
{ :include_blank => true }))
|
|
| 36 |
end %> |
|
| 35 | 37 |
</div> |
| 36 | 38 | |
| 37 | 39 |
<div class="splitcontentright"> |
| app/views/issues/_form_update.rhtml Sun Jun 15 14:27:25 2008 +0200 → app/views/issues/_form_update.rhtml Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 4 | 4 |
</div> |
| 5 | 5 |
<div class="splitcontentright"> |
| 6 | 6 |
<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
|
| 7 |
<%= content_tag('p', f.select(:fixed_version_id,
|
|
| 8 |
(@project.versions.sort.collect {|v| [v.name, v.id]}),
|
|
| 9 |
{ :include_blank => true })) unless @project.versions.empty? %>
|
|
| 7 |
<%= unless (@issue.fixed_version && |
|
| 8 |
(not User.current.allowed_to?(:view_issues, |
|
| 9 |
@issue.fixed_version.project)) || |
|
| 10 |
@project.related_versions.empty?) then |
|
| 11 |
content_tag('p', f.select(:fixed_version_id,
|
|
| 12 |
(@project.related_versions.sort.collect {|v| [v.name, v.id]}),
|
|
| 13 |
{ :include_blank => true }))
|
|
| 14 |
end %> |
|
| 10 | 15 |
</div> |
| app/views/issues/_pdf.rfpdf Sun Jun 15 14:27:25 2008 +0200 → app/views/issues/_pdf.rfpdf Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 86 | 86 |
pdf.SetFontStyle('B',9)
|
| 87 | 87 |
pdf.Cell(190,5, l(:label_history), "B") |
| 88 | 88 |
pdf.Ln |
| 89 |
for journal in issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
|
|
| 89 |
for journal in @journals
|
|
| 90 | 90 |
pdf.SetFontStyle('B',8)
|
| 91 | 91 |
pdf.Cell(190,5, format_time(journal.created_on) + " - " + journal.user.name) |
| 92 | 92 |
pdf.Ln |
| app/views/issues/bulk_edit.rhtml Sun Jun 15 14:27:25 2008 +0200 → app/views/issues/bulk_edit.rhtml Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 27 | 27 |
<label><%= l(:field_fixed_version) %>: |
| 28 | 28 |
<%= select_tag('fixed_version_id', content_tag('option', l(:label_no_change_option), :value => '') +
|
| 29 | 29 |
content_tag('option', l(:label_none), :value => 'none') +
|
| 30 |
options_from_collection_for_select(@project.versions, :id, :name)) %></label> |
|
| 30 |
options_from_collection_for_select(@project.related_versions, :id, :name)) %></label>
|
|
| 31 | 31 |
</p> |
| 32 | 32 | |
| 33 | 33 |
<p> |
| app/views/projects/roadmap.rhtml Sun Jun 15 14:27:25 2008 +0200 → app/views/projects/roadmap.rhtml Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 1 | 1 |
<h2><%=l(:label_roadmap)%></h2> |
| 2 | 2 | |
| 3 | 3 |
<% if @versions.empty? %> |
| 4 |
<p class="nodata"><%= l(:label_no_data) %></p> |
|
| 4 |
<p class="nodata"><%= l(:label_no_data) %></p>
|
|
| 5 | 5 |
<% else %> |
| 6 |
<div id="roadmap"> |
|
| 7 |
<% @versions.each do |version| %> |
|
| 8 |
<%= tag 'a', :name => version.name %> |
|
| 9 |
<h3 class="icon22 icon22-package"><%= link_to h(version.name), :controller => 'versions', :action => 'show', :id => version %></h3> |
|
| 10 |
<%= render :partial => 'versions/overview', :locals => {:version => version} %>
|
|
| 11 |
<%= render(:partial => "wiki/content", :locals => {:content => version.wiki_page.content}) if version.wiki_page %>
|
|
| 12 | ||
| 13 |
<% issues = version.fixed_issues.find(:all, |
|
| 14 |
:include => [:status, :tracker], |
|
| 15 |
:conditions => ["tracker_id in (#{@selected_tracker_ids.join(',')})"],
|
|
| 16 |
:order => "#{Tracker.table_name}.position, #{Issue.table_name}.id") unless @selected_tracker_ids.empty?
|
|
| 17 |
issues ||= [] |
|
| 18 |
%> |
|
| 19 |
<% if issues.size > 0 %> |
|
| 20 |
<fieldset class="related-issues"><legend><%= l(:label_related_issues) %></legend> |
|
| 21 |
<ul> |
|
| 22 |
<%- issues.each do |issue| -%> |
|
| 23 |
<li class="issue <%= 'closed' if issue.closed? %>"><%= link_to_issue(issue) %>: <%=h issue.subject %></li> |
|
| 24 |
<%- end -%> |
|
| 25 |
</ul> |
|
| 26 |
</fieldset> |
|
| 6 |
<div id="roadmap"> |
|
| 7 |
<% @versions.each do |version| %> |
|
| 8 |
<% issues = version_visible_issues(version,@project,@selected_tracker_ids) %> |
|
| 9 |
<% next if (version.project.id != @project.id && issues.empty?) %> |
|
| 10 |
<%= tag 'a', :name => version.name %> |
|
| 11 |
<h3 class="icon22 icon22-package"><%= link_to h(version.name), :controller => 'versions', :action => 'show', :id => version %></h3> |
|
| 12 |
<%= render :partial => 'versions/overview', :locals => {:version => version} %>
|
|
| 13 |
<%= render(:partial => "wiki/content", :locals => {:content => version.wiki_page.content}) if version.wiki_page %>
|
|
| 14 |
|
|
| 15 |
<% if issues.size > 0 %> |
|
| 16 |
<fieldset class="related-issues"><legend><%= l(:label_related_issues) %></legend> |
|
| 17 |
<ul> |
|
| 18 |
<%- issues.each do |issue| -%> |
|
| 19 |
<li class="issue <%= 'closed' if issue.closed? %>"> |
|
| 20 |
<%= link_to_issue(issue) %>: |
|
| 21 |
<%=h issue.subject %> |
|
| 22 |
<%= (" <em>(" + issue.project.name + ")</em>") unless issue.project.id == @project.id %>
|
|
| 23 |
</li> |
|
| 24 |
<%- end -%> |
|
| 25 |
</ul> |
|
| 26 |
</fieldset> |
|
| 27 |
<% end %> |
|
| 28 |
<% end %> |
|
| 29 |
</div> |
|
| 30 |
<% end %> |
|
| 31 |
|
|
| 32 |
<% content_for :sidebar do %> |
|
| 33 |
<% form_tag do %> |
|
| 34 |
<h3><%= l(:label_roadmap) %></h3> |
|
| 35 |
<% @trackers.each do |tracker| %> |
|
| 36 |
<label><%= check_box_tag "tracker_ids[]", tracker.id, (@selected_tracker_ids.include? tracker.id.to_s), :id => nil %> |
|
| 37 |
<%= tracker.name %></label><br /> |
|
| 38 |
<% end %> |
|
| 39 |
<br /> |
|
| 40 |
<label for="completed"><%= check_box_tag "completed", 1, params[:completed] %> <%= l(:label_show_completed_versions) %></label> |
|
| 41 |
<p><%= submit_tag l(:button_apply), :class => 'button-small' %></p> |
|
| 27 | 42 |
<% end %> |
| 28 |
<% end %> |
|
| 29 |
</div> |
|
| 30 |
<% end %> |
|
| 31 | ||
| 32 |
<% content_for :sidebar do %> |
|
| 33 |
<% form_tag do %> |
|
| 34 |
<h3><%= l(:label_roadmap) %></h3> |
|
| 35 |
<% @trackers.each do |tracker| %> |
|
| 36 |
<label><%= check_box_tag "tracker_ids[]", tracker.id, (@selected_tracker_ids.include? tracker.id.to_s), :id => nil %> |
|
| 37 |
<%= tracker.name %></label><br /> |
|
| 38 |
<% end %> |
|
| 39 |
<br /> |
|
| 40 |
<label for="completed"><%= check_box_tag "completed", 1, params[:completed] %> <%= l(:label_show_completed_versions) %></label> |
|
| 41 |
<p><%= submit_tag l(:button_apply), :class => 'button-small' %></p> |
|
| 42 |
<% end %> |
|
| 43 | ||
| 44 |
<h3><%= l(:label_version_plural) %></h3> |
|
| 45 |
<% @versions.each do |version| %> |
|
| 46 |
<%= link_to version.name, "##{version.name}" %><br />
|
|
| 47 |
<% end %> |
|
| 48 |
<% end %> |
|
| 49 | ||
| 50 |
<% html_title(l(:label_roadmap)) %> |
|
| 43 |
|
|
| 44 |
<h3><%= l(:label_version_plural) %></h3> |
|
| 45 |
<% @versions.each do |version| %> |
|
| 46 |
<%= link_to version.name, "##{version.name}" %><br />
|
|
| 47 |
<% end %> |
|
| 48 |
<% end %> |
|
| 49 |
|
|
| 50 |
<% html_title(l(:label_roadmap)) %> |
|
| app/views/versions/show.rhtml Sun Jun 15 14:27:25 2008 +0200 → app/views/versions/show.rhtml Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 31 | 31 |
<%= render :partial => 'versions/overview', :locals => {:version => @version} %>
|
| 32 | 32 |
<%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %>
|
| 33 | 33 | |
| 34 |
<% issues = @version.fixed_issues.find(:all, |
|
| 35 |
:include => [:status, :tracker], |
|
| 36 |
:order => "#{Tracker.table_name}.position, #{Issue.table_name}.id") %>
|
|
| 37 |
<% if issues.size > 0 %> |
|
| 34 |
<% if @issues.size > 0 %> |
|
| 38 | 35 |
<fieldset class="related-issues"><legend><%= l(:label_related_issues) %></legend> |
| 39 | 36 |
<ul> |
| 40 |
<% issues.each do |issue| -%> |
|
| 41 |
<li class="issue <%= 'closed' if issue.closed? %>"><%= link_to_issue(issue) %>: <%=h issue.subject %></li> |
|
| 37 |
<% @issues.each do |issue| -%> |
|
| 38 |
<li class="issue <%= 'closed' if issue.closed? %>"> |
|
| 39 |
<%= link_to_issue(issue) %>: <%=h issue.subject %> |
|
| 40 |
<%= (" <em>(" + issue.project.name + ")</em>") unless issue.project.id == @project.id %>
|
|
| 41 |
</li> |
|
| 42 | 42 |
<% end -%> |
| 43 | 43 |
</ul> |
| 44 | 44 |
</fieldset> |
| lib/redmine.rb Sun Jun 15 14:27:25 2008 +0200 → lib/redmine.rb Fri Jun 27 13:12:14 2008 +0200 | ||
|---|---|---|
| 116 | 116 |
menu.push :overview, { :controller => 'projects', :action => 'show' }
|
| 117 | 117 |
menu.push :activity, { :controller => 'projects', :action => 'activity' }
|
| 118 | 118 |
menu.push :roadmap, { :controller => 'projects', :action => 'roadmap' },
|
| 119 |
:if => Proc.new { |p| p.versions.any? }
|
|
| 119 |
:if => Proc.new { |p| p.related_versions.any? }
|
|
| 120 | 120 |
menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
|
| 121 | 121 |
menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
|
| 122 | 122 |
:html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
|