git-svn-id: http://redmine.rubyforge.org/svn/trunk@1480 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/0.8.0-RC1
@@ -19,7 +19,7 @@ class IssuesController < ApplicationController | |||
layout 'base' | |||
menu_item :new_issue, :only => :new | |||
before_filter :find_issue, :only => [:show, :edit, :destroy_attachment] | |||
before_filter :find_issue, :only => [:show, :edit, :reply, :destroy_attachment] | |||
before_filter :find_issues, :only => [:bulk_edit, :move, :destroy] | |||
before_filter :find_project, :only => [:new, :update_form, :preview] | |||
before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu] | |||
@@ -208,6 +208,26 @@ class IssuesController < ApplicationController | |||
flash.now[:error] = l(:notice_locking_conflict) | |||
end | |||
def reply | |||
journal = Journal.find(params[:journal_id]) if params[:journal_id] | |||
if journal | |||
user = journal.user | |||
text = journal.notes | |||
else | |||
user = @issue.author | |||
text = @issue.description | |||
end | |||
content = "#{ll(Setting.default_language, :text_user_wrote, user)}\n> " | |||
content << text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub("\n", "\n> ") + "\n\n" | |||
render(:update) { |page| | |||
page.replace_html "notes", content | |||
page.show 'update' | |||
page << "Form.Element.focus('notes');" | |||
page << "Element.scrollTo('update');" | |||
page << "$('notes').scrollTop = $('notes').scrollHeight - $('notes').clientHeight;" | |||
} | |||
end | |||
# Bulk edit a set of issues | |||
def bulk_edit | |||
if request.post? |
@@ -19,13 +19,16 @@ module JournalsHelper | |||
def render_notes(journal, options={}) | |||
content = '' | |||
editable = journal.editable_by?(User.current) | |||
if editable && !journal.notes.blank? | |||
links = [] | |||
links = [] | |||
if !journal.notes.blank? | |||
links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes", | |||
{ :controller => 'journals', :action => 'edit', :id => journal }, | |||
:title => l(:button_edit)) | |||
content << content_tag('div', links.join(' '), :class => 'contextual') | |||
:title => l(:button_edit)) if editable | |||
links << link_to_remote(image_tag('comment.png'), | |||
{ :url => {:controller => 'issues', :action => 'reply', :id => journal.journalized, :journal_id => journal} }, | |||
:title => l(:button_reply)) if options[:reply_links] | |||
end | |||
content << content_tag('div', links.join(' '), :class => 'contextual') unless links.empty? | |||
content << textilizable(journal, :notes) | |||
content_tag('div', content, :id => "journal-#{journal.id}-notes", :class => (editable ? 'wiki editable' : 'wiki')) | |||
end |
@@ -1,3 +1,4 @@ | |||
<% reply_links = authorize_for('issues', 'edit') -%> | |||
<% for journal in journals %> | |||
<div id="change-<%= journal.id %>" class="journal"> | |||
<h4><div style="float:right;"><%= link_to "##{journal.indice}", :anchor => "note-#{journal.indice}" %></div> | |||
@@ -8,6 +9,6 @@ | |||
<li><%= show_detail(detail) %></li> | |||
<% end %> | |||
</ul> | |||
<%= render_notes(journal) unless journal.notes.blank? %> | |||
<%= render_notes(journal, :reply_links => reply_links) unless journal.notes.blank? %> | |||
</div> | |||
<% end %> |
@@ -56,6 +56,12 @@ end %> | |||
</table> | |||
<hr /> | |||
<div class="contextual"> | |||
<%= link_to_remote(image_tag('comment.png'), | |||
{ :url => {:controller => 'issues', :action => 'reply', :id => @issue} }, | |||
:title => l(:button_reply)) if authorize_for('issues', 'edit') %> | |||
</div> | |||
<p><strong><%=l(:field_description)%></strong></p> | |||
<div class="wiki"> | |||
<%= textilizable @issue, :description, :attachments => @issue.attachments %> |
@@ -621,3 +621,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -626,3 +626,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -623,3 +623,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -622,3 +622,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -596,6 +596,7 @@ text_destroy_time_entries_question: %.02f hours were reported on the issues you | |||
text_destroy_time_entries: Delete reported hours | |||
text_assign_time_entries_to_project: Assign reported hours to the project | |||
text_reassign_time_entries: 'Reassign reported hours to this issue:' | |||
text_user_wrote: '%s wrote:' | |||
default_role_manager: Manager | |||
default_role_developper: Developer |
@@ -624,3 +624,4 @@ text_subprojects_destroy_warning: 'Sus subprojectos: %s también se eliminarán' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -621,3 +621,4 @@ text_subprojects_destroy_warning: 'Tämän alaprojekti(t): %s tullaan myös pois | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -596,6 +596,7 @@ text_destroy_time_entries_question: %.02f heures ont été enregistrées sur les | |||
text_destroy_time_entries: Supprimer les heures | |||
text_assign_time_entries_to_project: Reporter les heures sur le projet | |||
text_reassign_time_entries: 'Reporter les heures sur cette demande:' | |||
text_user_wrote: '%s a écrit:' | |||
default_role_manager: Manager | |||
default_role_developper: Développeur |
@@ -621,3 +621,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -622,3 +622,4 @@ enumeration_doc_categories: Dokumentum kategóriák | |||
enumeration_activities: Tevékenységek (idő rögzítés) | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -621,3 +621,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -622,3 +622,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -621,3 +621,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -623,3 +623,4 @@ label_and_its_subprojects: %s projektas ir jo subprojektai | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -622,3 +622,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -622,3 +622,4 @@ enumeration_doc_categories: Dokument-kategorier | |||
enumeration_activities: Aktiviteter (tidssporing) | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -621,3 +621,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -621,3 +621,4 @@ label_age: Age | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -621,3 +621,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -621,3 +621,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -625,3 +625,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -622,3 +622,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -622,3 +622,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -624,3 +624,4 @@ enumeration_activities: กิจกรรม (ใช้ในการติด | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -623,3 +623,4 @@ text_subprojects_destroy_warning: 'Its subproject(s): %s will be also deleted.' | |||
label_and_its_subprojects: %s and its subprojects | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -622,3 +622,4 @@ enumeration_doc_categories: 文件分類 | |||
enumeration_activities: 活動 (時間追蹤) | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
text_user_wrote: '%s wrote:' |
@@ -622,3 +622,4 @@ enumeration_doc_categories: 文档类别 | |||
enumeration_activities: 活动(时间跟踪) | |||
mail_subject_reminder: "%d issue(s) due in the next days" | |||
mail_body_reminder: "%d issue(s) that are assigned to you are due in the next %d days:" | |||
text_user_wrote: '%s wrote:' |
@@ -32,9 +32,9 @@ Redmine::AccessControl.map do |map| | |||
:queries => :index, | |||
:reports => :issue_report}, :public => true | |||
map.permission :add_issues, {:issues => :new} | |||
map.permission :edit_issues, {:issues => [:edit, :bulk_edit, :destroy_attachment]} | |||
map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit, :destroy_attachment]} | |||
map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]} | |||
map.permission :add_issue_notes, {:issues => :edit} | |||
map.permission :add_issue_notes, {:issues => [:edit, :reply]} | |||
map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin | |||
map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin | |||
map.permission :move_issues, {:issues => :move}, :require => :loggedin |
@@ -263,6 +263,22 @@ class IssuesControllerTest < Test::Unit::TestCase | |||
:content => 'Urgent', | |||
:attributes => { :selected => 'selected' } } | |||
end | |||
def test_reply_to_issue | |||
@request.session[:user_id] = 2 | |||
get :reply, :id => 1 | |||
assert_response :success | |||
assert_select_rjs :show, "update" | |||
assert_select_rjs :replace_html, "notes" | |||
end | |||
def test_reply_to_note | |||
@request.session[:user_id] = 2 | |||
get :reply, :id => 1, :journal_id => 2 | |||
assert_response :success | |||
assert_select_rjs :show, "update" | |||
assert_select_rjs :replace_html, "notes" | |||
end | |||
def test_post_edit | |||
@request.session[:user_id] = 2 |