-# redMine - project management software
-# Copyright (C) 2006-2008 Jean-Philippe Lang
+# Redmine - project management software
+# Copyright (C) 2006-2011 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class JournalsController < ApplicationController
- before_filter :find_journal, :only => [:edit]
+ before_filter :find_journal, :only => [:edit, :diff]
before_filter :find_issue, :only => [:new]
before_filter :find_optional_project, :only => [:index]
- before_filter :authorize, :only => [:new, :edit]
+ before_filter :authorize, :only => [:new, :edit, :diff]
accept_key_auth :index
-
+ menu_item :issues
+
helper :issues
helper :queries
include QueriesHelper
render_404
end
+ def diff
+ @issue = @journal.issue
+ if params[:detail_id].present?
+ @detail = @journal.details.find_by_id(params[:detail_id])
+ else
+ @detail = @journal.details.detect {|d| d.prop_key == 'description'}
+ end
+ (render_404; return false) unless @issue && @detail
+ @diff = Redmine::Helpers::Diff.new(@detail.value, @detail.old_value)
+ end
+
def new
journal = Journal.find(params[:journal_id]) if params[:journal_id]
if journal
end
def edit
+ (render_403; return false) unless @journal.editable_by?(User.current)
if request.post?
@journal.update_attributes(:notes => params[:notes]) if params[:notes]
@journal.destroy if @journal.details.empty? && @journal.notes.blank?
end
end
-private
+ private
+
def find_journal
@journal = Journal.find(params[:id])
- (render_403; return false) unless @journal.editable_by?(User.current)
@project = @journal.journalized.project
rescue ActiveRecord::RecordNotFound
render_404
-# redMine - project management software
-# Copyright (C) 2006 Jean-Philippe Lang
+# Redmine - project management software
+# Copyright (C) 2006-2011 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
end
end
- if !detail.value.blank?
+ if detail.property == 'attr' && detail.prop_key == 'description'
+ s = l(:text_journal_changed_no_detail, :label => label)
+ unless no_html
+ diff_link = link_to 'diff',
+ {:controller => 'journals', :action => 'diff', :id => detail.journal_id, :detail_id => detail.id},
+ :title => l(:label_view_diff)
+ s << " (#{ diff_link })"
+ end
+ s
+ elsif !detail.value.blank?
case detail.property
when 'attr', 'cf'
if !detail.old_value.blank?
-# redMine - project management software
-# Copyright (C) 2006-2007 Jean-Philippe Lang
+# Redmine - project management software
+# Copyright (C) 2006-2011 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
def create_journal
if @current_journal
# attributes changes
- (Issue.column_names - %w(id description root_id lft rgt lock_version created_on updated_on)).each {|c|
+ (Issue.column_names - %w(id root_id lft rgt lock_version created_on updated_on)).each {|c|
@current_journal.details << JournalDetail.new(:property => 'attr',
:prop_key => c,
:old_value => @issue_before_change.send(c),
-# redMine - project management software
-# Copyright (C) 2006 Jean-Philippe Lang
+# Redmine - project management software
+# Copyright (C) 2006-2011 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
class JournalDetail < ActiveRecord::Base
belongs_to :journal
-
- def before_save
- self.value = value[0..254] if value && value.is_a?(String)
- self.old_value = old_value[0..254] if old_value && old_value.is_a?(String)
- end
end
--- /dev/null
+<h2><%=h @issue.tracker %> #<%= @issue.id %></h2>
+<p><%= authoring @journal.created_on, @journal.user, :label => :label_updated_time_by %></p>
+
+<div class="text-diff">
+<%= simple_format_without_paragraph @diff.to_html %>
+</div>
+
+<p><%= link_to l(:button_back), issue_path(@issue), :onclick => 'history.back(); return false;' %></p>
+
+<% html_title "#{@issue.tracker.name} ##{@issue.id}: #{@issue.subject}" %>
text_are_you_sure: Are you sure ?
text_are_you_sure_with_children: "Delete issue and all child issues?"
text_journal_changed: "%{label} changed from %{old} to %{new}"
+ text_journal_changed_no_detail: "%{label} updated"
text_journal_set_to: "%{label} set to %{value}"
text_journal_deleted: "%{label} deleted (%{old})"
text_journal_added: "%{label} %{value} added"
error_no_tracker_in_project: "Aucun tracker n'est associé à ce projet. Vérifier la configuration du projet."
error_no_default_issue_status: "Aucun statut de demande n'est défini par défaut. Vérifier votre configuration (Administration -> Statuts de demandes)."
text_journal_changed: "%{label} changé de %{old} à %{new}"
+ text_journal_changed_no_detail: "%{label} mis à jour"
text_journal_set_to: "%{label} mis à %{value}"
text_journal_deleted: "%{label} %{old} supprimé"
text_journal_added: "%{label} %{value} ajouté"
--- /dev/null
+class ChangeJournalDetailsValuesToText < ActiveRecord::Migration
+ def self.up
+ change_column :journal_details, :old_value, :text
+ change_column :journal_details, :value, :text
+ end
+
+ def self.down
+ change_column :journal_details, :old_value, :string
+ change_column :journal_details, :value, :string
+ end
+end
:auto_complete => [:issues],
:context_menus => [:issues],
:versions => [:index, :show, :status_by],
- :journals => :index,
+ :journals => [:index, :diff],
:queries => :index,
:reports => [:issue_report, :issue_report_details]}
map.permission :add_issues, {:issues => [:new, :create, :update_form]}
.diff_out { background: #fcc; }
.diff_in { background: #cfc; }
+.text-diff {
+padding: 1em;
+background-color:#f6f6f6;
+color:#505050;
+border: 1px solid #e4e4e4;
+}
+
/***** Wiki *****/
div.wiki table {
border: 1px solid #505050;
value: "6"
prop_key: fixed_version_id
journal_id: 4
+journal_details_004:
+ old_value: "This word was removed and an other was"
+ property: attr
+ id: 4
+ value: "This word was and an other was added"
+ prop_key: description
+ journal_id: 3
-# redMine - project management software
-# Copyright (C) 2006-2008 Jean-Philippe Lang
+# Redmine - project management software
+# Copyright (C) 2006-2011 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
assert_equal 'application/atom+xml', @response.content_type
end
+ def test_diff
+ get :diff, :id => 3, :detail_id => 4
+ assert_response :success
+ assert_template 'diff'
+
+ assert_tag 'span',
+ :attributes => {:class => 'diff_out'},
+ :content => /removed/
+ assert_tag 'span',
+ :attributes => {:class => 'diff_in'},
+ :content => /added/
+ end
+
def test_reply_to_issue
@request.session[:user_id] = 2
get :new, :id => 6
-# redMine - project management software
-# Copyright (C) 2006-2007 Jean-Philippe Lang
+# Redmine - project management software
+# Copyright (C) 2006-2011 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
assert ActionMailer::Base.deliveries.empty?
end
+ def test_journalized_description
+ i = Issue.first
+ old_description = i.description
+ new_description = "This is the new description"
+
+ i.init_journal(User.find(2))
+ i.description = new_description
+ assert_difference 'Journal.count', 1 do
+ assert_difference 'JournalDetail.count', 1 do
+ i.save!
+ end
+ end
+
+ detail = JournalDetail.first(:order => 'id DESC')
+ assert_equal i, detail.journal.journalized
+ assert_equal 'attr', detail.property
+ assert_equal 'description', detail.prop_key
+ assert_equal old_description, detail.old_value
+ assert_equal new_description, detail.value
+ end
+
def test_saving_twice_should_not_duplicate_journal_details
i = Issue.find(:first)
i.init_journal(User.find(2), 'Some notes')