mirror of
https://github.com/redmine/redmine.git
synced 2025-10-26 07:46:17 +01:00
Load changesets and time entries tabs async (#3058).
Patch by Marius BALTEANU. git-svn-id: http://svn.redmine.org/redmine/trunk@18275 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
class IssuesController < ApplicationController
|
||||
default_search_scope :issues
|
||||
|
||||
before_action :find_issue, :only => [:show, :edit, :update]
|
||||
before_action :find_issue, :only => [:show, :edit, :update, :issue_tab]
|
||||
before_action :find_issues, :only => [:bulk_edit, :bulk_update, :destroy]
|
||||
before_action :authorize, :except => [:index, :new, :create]
|
||||
before_action :find_optional_project, :only => [:index, :new, :create]
|
||||
@@ -86,13 +86,10 @@ class IssuesController < ApplicationController
|
||||
|
||||
def show
|
||||
@journals = @issue.visible_journals_with_index
|
||||
@changesets = @issue.changesets.visible.preload(:repository, :user).to_a
|
||||
@has_changesets = @issue.changesets.visible.preload(:repository, :user).exists?
|
||||
@relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
|
||||
|
||||
if User.current.wants_comments_in_reverse_order?
|
||||
@journals.reverse!
|
||||
@changesets.reverse!
|
||||
end
|
||||
@journals.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
|
||||
if User.current.allowed_to?(:view_time_entries, @project)
|
||||
Issue.load_visible_spent_hours([@issue])
|
||||
@@ -109,7 +106,10 @@ class IssuesController < ApplicationController
|
||||
retrieve_previous_and_next_issue_ids
|
||||
render :template => 'issues/show'
|
||||
}
|
||||
format.api
|
||||
format.api {
|
||||
@changesets = @issue.changesets.visible.preload(:repository, :user).to_a
|
||||
@changesets.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
}
|
||||
format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' }
|
||||
format.pdf {
|
||||
send_file_headers! :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf"
|
||||
@@ -194,6 +194,21 @@ class IssuesController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def issue_tab
|
||||
return render_error :status => 422 unless request.xhr?
|
||||
tab = params[:name]
|
||||
|
||||
case tab
|
||||
when 'time_entries'
|
||||
@time_entries = @issue.time_entries.visible.preload(:activity, :user).to_a
|
||||
render :partial => 'issues/tabs/time_entries', :locals => {:time_entries => @time_entries}
|
||||
when 'changesets'
|
||||
@changesets = @issue.changesets.visible.preload(:repository, :user).to_a
|
||||
changesets.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
render :partial => 'issues/tabs/changesets', :locals => {:changesets => @changesets}
|
||||
end
|
||||
end
|
||||
|
||||
# Bulk edit/copy a set of issues
|
||||
def bulk_edit
|
||||
@issues.sort!
|
||||
|
||||
@@ -557,8 +557,9 @@ module IssuesHelper
|
||||
tabs << {:name => 'notes', :label => :label_issue_history_notes, :onclick => 'showIssueHistory("notes", this.href)'} if journals_with_notes.any?
|
||||
tabs << {:name => 'properties', :label => :label_issue_history_properties, :onclick => 'showIssueHistory("properties", this.href)'} if journals_without_notes.any?
|
||||
end
|
||||
tabs << {:name => 'time_entries', :label => :label_time_entry_plural, :partial => 'issues/tabs/time_entries', :locals => {:time_entries => @time_entries}} if User.current.allowed_to?(:view_time_entries, @project) && @issue.spent_hours > 0
|
||||
tabs << {:name => 'changesets', :label => :label_associated_revisions, :partial => 'issues/tabs/changesets', :locals => {:changesets => @changesets}} if @changesets.present?
|
||||
tabs << {:name => 'time_entries', :label => :label_time_entry_plural, :remote => true, :onclick => "getRemoteTab('time_entries', '#{tab_issue_path(@issue, :name => 'time_entries')}', '#{issue_path(@issue, :tab => 'time_entries')}')"} if User.current.allowed_to?(:view_time_entries, @project) && @issue.spent_hours > 0
|
||||
tabs << {:name => 'changesets', :label => :label_associated_revisions, :remote => true, :onclick => "getRemoteTab('changesets', '#{tab_issue_path(@issue, :name => 'changesets')}', '#{issue_path(@issue, :tab => 'changesets')}')"} if @has_changesets
|
||||
tabs
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
</div>
|
||||
|
||||
<% tabs.each do |tab| -%>
|
||||
<%= content_tag('div', render(:partial => tab[:partial], :locals => {:tab => tab} ),
|
||||
<%= content_tag('div', (render(:partial => tab[:partial], :locals => {:tab => tab}) if tab[:partial]) ,
|
||||
:id => "tab-content-#{tab[:name]}",
|
||||
:style => (tab[:name] != selected_tab ? 'display:none' : nil),
|
||||
:class => 'tab-content') if tab[:partial] %>
|
||||
:class => 'tab-content') if tab[:partial] || tab[:remote] %>
|
||||
<% end -%>
|
||||
|
||||
<%= javascript_tag default_action if default_action %>
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
<% changesets.each do |changeset| %>
|
||||
<div class="changeset">
|
||||
<p><%= link_to_revision(changeset, changeset.repository,
|
||||
:text => "#{l(:label_revision)} #{changeset.format_identifier}") %>
|
||||
<% if changeset.filechanges.any? && User.current.allowed_to?(:browse_repository, changeset.project) %>
|
||||
(<%= link_to(l(:label_diff),
|
||||
:controller => 'repositories',
|
||||
:action => 'diff',
|
||||
:id => changeset.project,
|
||||
:repository_id => changeset.repository.identifier_param,
|
||||
:path => "",
|
||||
:rev => changeset.identifier) %>)
|
||||
<% end %>
|
||||
<br />
|
||||
<span class="author"><%= authoring(changeset.committed_on, changeset.author) %></span></p>
|
||||
<div class="wiki changeset-comments">
|
||||
<%= format_changeset_comments changeset %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,4 +1,4 @@
|
||||
<% tab[:locals][:changesets].each do |changeset| %>
|
||||
<% @changesets.each do |changeset| %>
|
||||
<div id="changeset-<%= changeset.id %>" class="changeset journal">
|
||||
<h4>
|
||||
<%= avatar(changeset.user, :size => "24") %>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<% for time_entry in tab[:locals][:time_entries] %>
|
||||
<% for time_entry in time_entries%>
|
||||
<div id="time-entry-<%= time_entry.id %>" class="time_entry journal">
|
||||
<% if time_entry.editable_by?(User.current) -%>
|
||||
<div class="contextual">
|
||||
|
||||
@@ -188,6 +188,7 @@ Rails.application.routes.draw do
|
||||
member do
|
||||
# Used when updating the form of an existing issue
|
||||
patch 'edit', :to => 'issues#edit'
|
||||
get 'tab/:name', :action => 'issue_tab', :as => 'tab'
|
||||
end
|
||||
collection do
|
||||
match 'bulk_edit', :via => [:get, :post]
|
||||
|
||||
@@ -94,7 +94,7 @@ Redmine::AccessControl.map do |map|
|
||||
|
||||
map.project_module :issue_tracking do |map|
|
||||
# Issues
|
||||
map.permission :view_issues, {:issues => [:index, :show],
|
||||
map.permission :view_issues, {:issues => [:index, :show, :issue_tab],
|
||||
:auto_complete => [:issues],
|
||||
:context_menus => [:issues],
|
||||
:versions => [:index, :show, :status_by],
|
||||
|
||||
@@ -385,6 +385,24 @@ function showIssueHistory(journal, url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function getRemoteTab(name, remote_url, url) {
|
||||
$('#tab-content-' + name).parent().find('.tab-content').hide();
|
||||
$('#tab-content-' + name).parent().find('div.tabs a').removeClass('selected');
|
||||
$('#tab-' + name).addClass('selected')
|
||||
|
||||
replaceInHistory(url)
|
||||
|
||||
$.ajax({
|
||||
url: remote_url,
|
||||
type: 'get',
|
||||
success: function(data){
|
||||
$('#tab-content-' + name).html(data).show();
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//replaces current URL with the "href" attribute of the current link
|
||||
//(only triggered if supported by browser)
|
||||
function replaceInHistory(url) {
|
||||
|
||||
@@ -2168,9 +2168,11 @@ class IssuesControllerTest < Redmine::ControllerTest
|
||||
project.disable_module! :repository
|
||||
|
||||
@request.session[:user_id] = 2
|
||||
get :show, :params => {
|
||||
:id => issue.id
|
||||
}
|
||||
get :issue_tab, :params => {
|
||||
:id => issue.id,
|
||||
:name => 'changesets'
|
||||
},
|
||||
:xhr => true
|
||||
|
||||
assert_select 'a[href=?]', '/projects/ecookbook/repository/10/revisions/3'
|
||||
end
|
||||
@@ -2560,6 +2562,13 @@ class IssuesControllerTest < Redmine::ControllerTest
|
||||
assert_select 'div.tabs a[id=?]', 'tab-time_entries', :text => 'Spent time'
|
||||
end
|
||||
|
||||
get :issue_tab, :params => {
|
||||
:id => 3,
|
||||
:name => 'time_entries'
|
||||
},
|
||||
:xhr => true
|
||||
assert_response :success
|
||||
|
||||
assert_select 'div[id=?]', 'time-entry-3' do
|
||||
assert_select 'a[title=?][href=?]', 'Edit', '/time_entries/3/edit'
|
||||
assert_select 'a[title=?][href=?]', 'Delete', '/time_entries/3'
|
||||
|
||||
@@ -35,6 +35,8 @@ class RoutingIssuesTest < Redmine::RoutingTest
|
||||
should_route 'GET /issues/64/edit' => 'issues#edit', :id => '64'
|
||||
should_route 'PUT /issues/64' => 'issues#update', :id => '64'
|
||||
should_route 'DELETE /issues/64' => 'issues#destroy', :id => '64'
|
||||
|
||||
should_route "GET /issues/3/tab/time_entries" => 'issues#issue_tab', :id => '3', :name => 'time_entries'
|
||||
end
|
||||
|
||||
def test_issues_bulk_edit
|
||||
|
||||
Reference in New Issue
Block a user