05_load-changesets-and-time-entries-tabs-async_v2.patch

Marius BALTEANU, 2017-07-02 10:56

Download (10.7 KB)

View differences:

app/controllers/issues_controller.rb
18 18
class IssuesController < ApplicationController
19 19
  default_search_scope :issues
20 20

  
21
  before_action :find_issue, :only => [:show, :edit, :update]
21
  before_action :find_issue, :only => [:show, :edit, :update, :issue_tab]
22 22
  before_action :find_issues, :only => [:bulk_edit, :bulk_update, :destroy]
23 23
  before_action :authorize, :except => [:index, :new, :create]
24 24
  before_action :find_optional_project, :only => [:index, :new, :create]
......
83 83

  
84 84
  def show
85 85
    @journals = @issue.visible_journals_with_index
86
    @changesets = @issue.changesets.visible.preload(:repository, :user).to_a
86
    @has_changesets = @issue.changesets.visible.preload(:repository, :user).exists?
87 87
    @relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
88 88

  
89
    if User.current.wants_comments_in_reverse_order?
90
      @journals.reverse!
91
      @changesets.reverse!
92
    end
89
    @journals.reverse! if User.current.wants_comments_in_reverse_order?
93 90

  
94 91
    if User.current.allowed_to?(:view_time_entries, @project)
95 92
      Issue.load_visible_spent_hours([@issue])
......
106 103
        retrieve_previous_and_next_issue_ids
107 104
        render :template => 'issues/show'
108 105
      }
109
      format.api
106
      format.api {
107
        @changesets = @issue.changesets.visible.preload(:repository, :user).to_a
108
        @changesets.reverse! if User.current.wants_comments_in_reverse_order?
109
      }
110 110
      format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' }
111 111
      format.pdf  {
112 112
        send_file_headers! :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf"
......
191 191
    end
192 192
  end
193 193

  
194
  def issue_tab
195
    return render_error :status => 422 unless request.xhr?
196
    tab = params[:name]
197

  
198
    case tab
199
    when 'time_entries'
200
      @time_entries = @issue.time_entries.visible.preload(:activity, :user).to_a
201
      render :partial => 'issues/tabs/time_entries', :locals => {:time_entries => @time_entries}
202
    when 'changesets'
203
      @changesets = @issue.changesets.visible.preload(:repository, :user).to_a
204
      changesets.reverse! if User.current.wants_comments_in_reverse_order?
205
      render :partial => 'issues/tabs/changesets', :locals => {:changesets => @changesets}
206
    end
207
  end
208

  
194 209
  # Bulk edit/copy a set of issues
195 210
  def bulk_edit
196 211
    @issues.sort!
app/helpers/issues_helper.rb
552 552
      tabs << {:name => 'notes', :label => :label_issue_history_notes, :onclick => 'showIssueHistory("notes", this.href)'} if journals_with_notes.any?
553 553
      tabs << {:name => 'properties', :label => :label_issue_history_properties, :onclick => 'showIssueHistory("properties", this.href)'} if journals_without_notes.any?
554 554
    end
555
    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
556
    tabs << {:name => 'changesets', :label => :label_associated_revisions, :partial => 'issues/tabs/changesets', :locals => {:changesets => @changesets}} if @changesets.present?
555
    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
556
    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
557 557
    tabs
558 558
  end
559

  
559 560
end
app/views/common/_tabs.html.erb
19 19
</div>
20 20

  
21 21
<% tabs.each do |tab| -%>
22
  <%= content_tag('div', render(:partial => tab[:partial], :locals => {:tab => tab} ),
22
  <%= content_tag('div', (render(:partial => tab[:partial], :locals => {:tab => tab}) if tab[:partial]) ,
23 23
                       :id => "tab-content-#{tab[:name]}",
24 24
                       :style => (tab[:name] != selected_tab ? 'display:none' : nil),
25
                       :class => 'tab-content') if tab[:partial] %>
25
                       :class => 'tab-content') if tab[:partial] || tab[:remote] %>
26 26
<% end -%>
27 27

  
28 28
<%= javascript_tag default_action if default_action %>
app/views/issues/_changesets.html.erb
1
<% changesets.each do |changeset| %>
2
    <div class="changeset">
3
    <p><%= link_to_revision(changeset, changeset.repository,
4
                            :text => "#{l(:label_revision)} #{changeset.format_identifier}") %>
5
        <% if changeset.filechanges.any? && User.current.allowed_to?(:browse_repository, changeset.project) %>
6
        (<%= link_to(l(:label_diff),
7
               :controller => 'repositories',
8
               :action => 'diff',
9
               :id     => changeset.project,
10
               :repository_id => changeset.repository.identifier_param,
11
               :path   => "",
12
               :rev    => changeset.identifier) %>)
13
        <% end %>
14
        <br />
15
        <span class="author"><%= authoring(changeset.committed_on, changeset.author) %></span></p>
16
    <div class="wiki changeset-comments">
17
        <%= format_changeset_comments changeset %>
18
    </div>
19
    </div>
20
<% end %>
app/views/issues/tabs/_changesets.html.erb
1
<% tab[:locals][:changesets].each do |changeset| %>
1
<% @changesets.each do |changeset| %>
2 2
  <div id="changeset-<%= changeset.id %>" class="changeset journal">
3 3
    <h4>
4 4
      <%= avatar(changeset.user, :size => "24") %>
app/views/issues/tabs/_time_entries.html.erb
1
<% for time_entry in tab[:locals][:time_entries] %>
1
<% for time_entry in time_entries%>
2 2
  <div id="time-entry-<%= time_entry.id %>" class="time_entry journal">
3 3
    <% if time_entry.editable_by?(User.current) -%>
4 4
      <div class="contextual">
config/routes.rb
187 187
    member do
188 188
      # Used when updating the form of an existing issue
189 189
      patch 'edit', :to => 'issues#edit'
190
      get 'tab/:name', :action => 'issue_tab', :as => 'tab'
190 191
    end
191 192
    collection do
192 193
      match 'bulk_edit', :via => [:get, :post]
lib/redmine.rb
91 91

  
92 92
  map.project_module :issue_tracking do |map|
93 93
    # Issues
94
    map.permission :view_issues, {:issues => [:index, :show],
94
    map.permission :view_issues, {:issues => [:index, :show, :issue_tab],
95 95
                                  :auto_complete => [:issues],
96 96
                                  :context_menus => [:issues],
97 97
                                  :versions => [:index, :show, :status_by],
public/javascripts/application.js
369 369
  return false;
370 370
}
371 371

  
372
function getRemoteTab(name, remote_url, url) {
373
  $('#tab-content-' + name).parent().find('.tab-content').hide();
374
  $('#tab-content-' + name).parent().find('div.tabs a').removeClass('selected');
375
  $('#tab-' + name).addClass('selected')
376

  
377
  replaceInHistory(url)
378

  
379
  $.ajax({
380
    url: remote_url,
381
    type: 'get',
382
    success: function(data){
383
      $('#tab-content-' + name).html(data).show();
384
    }
385
  });
386

  
387
  return false;
388
}
389

  
372 390
//replaces current URL with the "href" attribute of the current link
373 391
//(only triggered if supported by browser)
374 392
function replaceInHistory(url) {
test/functional/issues_controller_test.rb
1965 1965
    project.disable_module! :repository
1966 1966

  
1967 1967
    @request.session[:user_id] = 2
1968
    get :show, :params => {
1969
        :id => issue.id
1968
    xhr :get, :issue_tab, :params => {
1969
        :id => issue.id,
1970
        :name => 'changesets'
1970 1971
      }
1971 1972

  
1972 1973
    assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
......
2327 2328
      assert_select 'div.tabs a[id=?]', 'tab-time_entries', :text => 'Spent time'
2328 2329
    end
2329 2330

  
2331
    xhr :get, :issue_tab, :params => {
2332
        :id => 3,
2333
        :name => 'time_entries'
2334
      }
2335
    assert_response :success
2336

  
2330 2337
    assert_select 'div[id=?]', 'time-entry-3' do
2331 2338
      assert_select 'a[title=?][href=?]', 'Edit', '/time_entries/3/edit'
2332 2339
      assert_select 'a[title=?][href=?]', 'Delete', '/time_entries/3'
test/integration/routing/issues_test.rb
33 33
    should_route 'GET /issues/64/edit' => 'issues#edit', :id => '64'
34 34
    should_route 'PUT /issues/64' => 'issues#update', :id => '64'
35 35
    should_route 'DELETE /issues/64' => 'issues#destroy', :id => '64'
36

  
37
    should_route "GET /issues/3/tab/time_entries" => 'issues#issue_tab', :id => '3', :name => 'time_entries'
36 38
  end
37 39

  
38 40
  def test_issues_bulk_edit