master_1565.diff

patch against master - Jens Krämer, 2015-02-09 13:27

Download (11.5 KB)

View differences:

app/controllers/my_controller.rb
22 22

  
23 23
  helper :issues
24 24
  helper :users
25
  helper :queries
25 26
  helper :custom_fields
26 27

  
27 28
  BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues,
......
45 46
  # Show user's page
46 47
  def page
47 48
    @user = User.current
49
    @all_blocks = Redmine::Views::MyPage::Block.all_blocks
48 50
    @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT
49 51
  end
50 52

  
......
139 141
  # User's page layout configuration
140 142
  def page_layout
141 143
    @user = User.current
144
    @all_blocks = Redmine::Views::MyPage::Block.all_blocks
142 145
    @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup
146
    blocks_in_use = @blocks.values.flatten
147

  
148
    # users may lose access to issue queries, it doesnt hurt to clean up their
149
    # layout from time to time:
150
    if (inaccessible_blocks = blocks_in_use - @all_blocks.keys).any?
151
      %w(top left right).each do |f|
152
        @blocks[f] -= inaccessible_blocks if @blocks[f]
153
      end
154
      @user.pref[:my_page_layout] = @blocks
155
      @user.pref.save
156
    end
157

  
143 158
    @block_options = []
144 159
    BLOCKS.each do |k, v|
145
      unless @blocks.values.flatten.include?(k)
160
      unless blocks_in_use.include?(k)
146 161
        @block_options << [l("my.blocks.#{v}", :default => [v, v.to_s.humanize]), k.dasherize]
147 162
      end
148 163
    end
164

  
165
    @issue_query_block_options = []
166
    Redmine::Views::MyPage::Block.issue_query_blocks.each do |id, name|
167
      unless blocks_in_use.include?(id)
168
        @issue_query_block_options << [name, id]
169
      end
170
    end
149 171
  end
150 172

  
151 173
  # Add a block to user's page
......
153 175
  # params[:block] : id of the block to add
154 176
  def add_block
155 177
    block = params[:block].to_s.underscore
156
    if block.present? && BLOCKS.key?(block)
178
    if block.present? && Redmine::Views::MyPage::Block.all_blocks.key?(block)
157 179
      @user = User.current
158 180
      layout = @user.pref[:my_page_layout] || {}
159 181
      # remove if already present in a group
app/helpers/my_helper.rb
31 31
    Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).to_a
32 32
  end
33 33

  
34
  def mypage_available_block_options
35
    options = options_for_select(@block_options)
36
    options += grouped_options_for_select([[l(:label_query_plural), @issue_query_block_options]]) if @issue_query_block_options.any?
37
    return options
38
  end
39

  
40
  def render_mypage_box(block, user = @user)
41
    locals = { user: user }
42
    partial = case block.to_s
43
    when /^issue_query_(\w+)$/
44
      locals[:query] = IssueQuery.visible.find $1
45
      "my/blocks/issue_query"
46
    else
47
      "my/blocks/#{block}"
48
    end
49
    render partial: partial, locals: locals
50
  end
51

  
34 52
  def issuesassignedtome_items
35 53
    Issue.visible.open.
36 54
      where(:assigned_to_id => ([User.current.id] + User.current.group_ids)).
app/views/my/_block.html.erb
5 5
    </div>
6 6

  
7 7
    <div class="handle">
8
    <%= render :partial => "my/blocks/#{block_name}", :locals => { :user => user } %>
8
      <%= render_mypage_box block_name, user %>
9 9
    </div>
10 10
</div>
app/views/my/blocks/_issue_query.html.erb
1
<h3>
2
  <%= link_to query.name, query.project ? project_issues_path(query.project, query_id: query.id) : issues_path(query_id: query.id) %>
3
  (<%= link_to_project(query.project) + ', ' if query.project %><%= query.issue_count %>)
4
</h3>
5

  
6
<% @issue_count_by_group = query.issue_count_by_group %>
7

  
8
<% if query.issue_count > 0 %>
9
  <%= form_tag({}) do %>
10
    <table class="list issues">
11
      <thead><tr>
12
        <% query.inline_columns.each do |column| %>
13
          <th><%= column.caption %></th>
14
        <% end %>
15
      </tr></thead>
16
      <% previous_group = false %>
17
      <tbody>
18
      <% issue_list(query.issues(limit: 10)) do |issue, level| -%>
19

  
20
        <% if query.grouped? && (group = query.group_by_column.value(issue)) != previous_group %>
21
          <% reset_cycle %>
22
          <tr class="group open">
23
            <td colspan="<%= query.inline_columns.size + 2 %>">
24
              <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
25
              <%= group.blank? ? l(:label_none) : column_content(query.group_by_column, issue) %> <span class="count"><%= @issue_count_by_group[group] %></span>
26
              <%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}",
27
                                   "toggleAllRowGroups(this)", :class => 'toggle-all') %>
28
            </td>
29
          </tr>
30
          <% previous_group = group %>
31
        <% end %>
32

  
33
        <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
34
          <td class="id">
35
            <%= check_box_tag("ids[]", issue.id, false, :style => 'display:none;', :id => nil) %>
36
            <%= link_to(issue.id, issue_path(issue)) %>
37
          </td>
38
          <%= raw query.inline_columns.reject{|c| c.name == :id}.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, issue)}</td>"}.join %>
39
        </tr>
40

  
41
      <% end %>
42
      </tbody>
43
    </table>
44
  <% end %>
45

  
46
<% else %>
47
  <p class="nodata"><%= l(:label_no_data) %></p>
48
<% end %>
49

  
50
<% content_for :header_tags do %>
51
<%= auto_discovery_link_tag(:atom,
52
                            {controller: 'issues', action: 'index', query_id: query.id, project_id: query.project.try(:identifier),
53
                             format: 'atom', key: User.current.rss_key},
54
                             {:title => query.name}) %>
55
<% end %>
56

  
app/views/my/page.html.erb
6 6

  
7 7
<div id="list-top">
8 8
  <% @blocks['top'].each do |b|
9
     next unless MyController::BLOCKS.keys.include? b  %>
9
     next unless @all_blocks.keys.include? b  %>
10 10
  <div class="mypage-box">
11
    <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %>
11
    <%= render_mypage_box b %>
12 12
  </div>
13 13
  <% end if @blocks['top'] %>
14 14
</div>
15 15

  
16 16
<div id="list-left" class="splitcontentleft">
17 17
  <% @blocks['left'].each do |b|
18
     next unless MyController::BLOCKS.keys.include? b %>
18
     next unless @all_blocks.keys.include? b %>
19 19
  <div class="mypage-box">
20
    <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %>
20
    <%= render_mypage_box b %>
21 21
  </div>
22 22
  <% end if @blocks['left'] %>
23 23
</div>
24 24

  
25 25
<div id="list-right" class="splitcontentright">
26 26
  <% @blocks['right'].each do |b|
27
     next unless MyController::BLOCKS.keys.include? b %>
27
     next unless @all_blocks.keys.include? b %>
28 28
  <div class="mypage-box">
29
    <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %>
29
    <%= render_mypage_box b %>
30 30
  </div>
31 31
  <% end if @blocks['right'] %>
32 32
</div>
app/views/my/page_layout.html.erb
3 3
  <%= form_tag({:action => "add_block"}, :id => "block-form") do %>
4 4
  <%= label_tag('block-select', l(:label_my_page_block)) %>:
5 5
  <%= select_tag 'block',
6
                 content_tag('option') + options_for_select(@block_options),
6
                 content_tag('option') + mypage_available_block_options,
7 7
                 :id => "block-select" %>
8 8
  <%= link_to l(:button_add), '#', :onclick => '$("#block-form").submit()', :class => 'icon icon-add' %>
9 9
  <% end %>
......
15 15

  
16 16
<div id="list-top" class="block-receiver">
17 17
  <% @blocks['top'].each do |b|
18
     next unless MyController::BLOCKS.keys.include? b %>
18
     next unless @all_blocks.keys.include? b %>
19 19
  <%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %>
20 20
  <% end if @blocks['top'] %>
21 21
</div>
22 22

  
23 23
<div id="list-left" class="splitcontentleft block-receiver">
24 24
  <% @blocks['left'].each do |b|
25
     next unless MyController::BLOCKS.keys.include? b %>
25
     next unless @all_blocks.keys.include? b %>
26 26
  <%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %>
27 27
  <% end if @blocks['left'] %>
28 28
</div>
29 29

  
30 30
<div id="list-right" class="splitcontentright block-receiver">
31 31
  <% @blocks['right'].each do |b|
32
     next unless MyController::BLOCKS.keys.include? b %>
32
     next unless @all_blocks.keys.include? b %>
33 33
  <%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %>
34 34
  <% end if @blocks['right'] %>
35 35
</div>
lib/redmine/views/my_page/block.rb
19 19
  module Views
20 20
    module MyPage
21 21
      module Block
22
        def self.all_blocks
23
          MyController::BLOCKS.merge issue_query_blocks
24
        end
25

  
26
        def self.issue_query_blocks
27
          Hash[IssueQuery.visible.map{|q| ["issue_query_#{q.id}", q.name]}]
28
        end
29

  
22 30
        def self.additional_blocks
23 31
          @@additional_blocks ||= Dir.glob("#{Redmine::Plugin.directory}/*/app/views/my/blocks/_*.{rhtml,erb}").inject({}) do |h,file|
24 32
            name = File.basename(file).split('.').first.gsub(/^_/, '')
test/functional/my_controller_test.rb
19 19

  
20 20
class MyControllerTest < ActionController::TestCase
21 21
  fixtures :users, :email_addresses, :user_preferences, :roles, :projects, :members, :member_roles,
22
  :queries, :enabled_modules,
22 23
  :issues, :issue_statuses, :trackers, :enumerations, :custom_fields, :auth_sources
23 24

  
24 25
  def setup
......
37 38
    assert_template 'page'
38 39
  end
39 40

  
41
  def test_page_with_custom_query
42
    preferences = User.find(2).pref
43
    issue = Issue.find 1
44
    issue.update_attribute :tracker_id, 3
45
    q = IssueQuery.find 4
46

  
47
    preferences[:my_page_layout] = {'top' => ["issue_query_#{q.id}"]}
48
    preferences.save!
49

  
50
    get :page
51
    assert_response :success
52
    assert_select 'h3', /#{q.name}/
53
    assert_select 'td.id a', /#{issue.id}/
54
    assert_select 'td.subject a', /print recipes/
55
  end
56

  
57
  def test_page_layout_should_remove_inaccessible_query
58
    user = User.find 2
59
    q = IssueQuery.find 3
60
    assert !IssueQuery.visible(user).include?(q)
61
    preferences = user.pref
62
    preferences[:my_page_layout] = {'top' => ["issue_query_#{q.id}"]}
63
    preferences.save!
64

  
65
    get :page_layout
66
    assert_response :success
67
    user.reload
68
    preferences = user.pref
69
    assert_equal [], preferences[:my_page_layout]['top']
70
  end
71

  
40 72
  def test_page_with_timelog_block
41 73
    preferences = User.find(2).pref
42 74
    preferences[:my_page_layout] = {'top' => ['timelog']}