0001-Implements-grid-as-in-divgrid-minimal-4.1.1.patch

For Redmine 4.1.1 - Frederico Camara, 2020-04-08 20:44

Download (37.9 KB)

View differences:

app/views/roles/permissions.html.erb
24 24
<% @roles.each do |role| %>
25 25
    <%= hidden_field_tag "permissions[#{role.id}][]", '', :id => nil %>
26 26
<% end %>
27
<div class="autoscroll">
28
<table class="list permissions">
29
<thead>
30
    <tr>
31
    <th><%=l(:label_permissions)%></th>
27

  
28
<%= stylesheet_link_tag 'divgrid' %>
29
<%= javascript_include_tag 'divgrid' %>
30

  
31
<div style="position: relative; overflow: hidden; white-space: nowrap; border-width: 1px; border-style: solid; border-color: #CCC;">
32
  <!-- Cell 0 -->
33
  <div id="g_bl" style="position: absolute; top: 0px; left: 0px; z-index: 2;">
34
    <div class="g_c g_h">&nbsp;</div>
35
  </div>
36
  <!-- Line 0  -->
37
  <div id="g_fl" class="ibf" style="position: absolute; top: 0px; left: 0px; right: 12px; overflow: hidden; z-index: 1;">
38
    <div style="display: inline-block;">
39
      <div class="g_c">&nbsp;</div>
40
    </div>
32 41
    <% @roles.each do |role| %>
33
    <th>
34
        <%= link_to_function('',
35
                             "toggleCheckboxesBySelector('input.role-#{role.id}')",
36
                             :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
37
                             :class => 'icon-only icon-checked') %>
38
        <%= content_tag(role.builtin? ? 'em' : 'span', role.name) %>
39
    </th>
42
      <div style="display: inline-block;">
43
        <div class="g_c g_h">
44
          <%= link_to_function('',
45
                               "toggleCheckboxesBySelector('input.role-#{role.id}')",
46
                               :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
47
                               :class => 'icon-only icon-checked') %>
48
          <%= content_tag(role.builtin? ? 'em' : 'span', role.name) %>
49
        </div>
50
      </div>
40 51
    <% end %>
41
    </tr>
42
</thead>
43
<tbody>
44
<% perms_by_module = @permissions.group_by {|p| p.project_module.to_s} %>
45
<% perms_by_module.keys.sort.each do |mod| %>
46
    <% unless mod.blank? %>
47
        <tr class="group open">
48
          <td>
49
            <span class="expander icon icon-expended" onclick="toggleRowGroup(this);">&nbsp;</span>
50
            <%= l_or_humanize(mod, :prefix => 'project_module_') %>
51
          </td>
52
          <% @roles.each do |role| %>
53
          <td class="role"><%= role.name %></td>
54
          <% end %>
55
        </tr>
52
  </div>
53
  <!-- Row 0 -->
54
  <div id="g_fr" style="position: absolute; top: 0px; left: 0px; bottom: 12px; overflow: hidden; z-index: 1;">
55
    <% perms_by_module = @permissions.group_by {|p| p.project_module.to_s} %>
56
    <% even = true %>
57
    <% perms_by_module.keys.sort.each do |mod| %>
58
      <div class="g_c g_v g_s<%= (even)? " g_e":" g_o" %>">
59
        <%= l_or_humanize(mod, :prefix => 'project_module_') %>
60
      </div>
61
      <% even = !even %>
62
      <% perms_by_module[mod].each do |permission| %>
63
        <div class="g_c g_v<%= (even)? " g_e":" g_o" %>">
64
          <% even = !even %>
65
          <%= link_to_function('',
66
                               "toggleCheckboxesBySelector('input.permission-#{permission.name}')",
67
                               :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
68
                               :class => 'icon-only icon-checked') %>
69
          <%= l_or_humanize(permission.name, :prefix => 'permission_') %>
70
        </div>
71
      <% end %>
56 72
    <% end %>
57
    <% perms_by_module[mod].each do |permission| %>
58
        <% humanized_perm_name = l_or_humanize(permission.name, :prefix => 'permission_') %>
59
        <tr class="permission-<%= permission.name %>">
60
        <td class="name">
61
            <%= link_to_function('',
62
                                 "toggleCheckboxesBySelector('.permission-#{permission.name} input')",
63
                                 :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
64
                                 :class => 'icon-only icon-checked') %>
65
            <%= humanized_perm_name %>
66
        </td>
67
        <% @roles.each do |role| %>
68
          <% if role.setable_permissions.include? permission %>
69
            <td title="<%= "#{humanized_perm_name} (#{role.name})" %>">
70
              <%= check_box_tag "permissions[#{role.id}][]", permission.name, (role.permissions.include? permission.name), :id => nil, :class => "role-#{role.id}" %>
71
            </td>
72
          <% else %>
73
            <td></td>
73
  </div>
74
  <!-- Body -->
75
  <div id="g_bd" class="ibf" style="width: 100%; max-height: 80vh; overflow: scroll;" onscroll="g_scroll(this, 'g_fl', 'g_fr')">
76
    <div style="display: inline-block;"></div>
77
    <% @roles.each do |role| %>
78
      <div style="display: inline-block;">
79
        <% even = true %>
80
        <% perms_by_module.keys.sort.each do |mod| %>
81
          <div class="g_c<%= " g_s" unless role == @roles.last %><%= (even)? " g_e":" g_o" %>"></div>
82
          <% even = !even %>
83
          <% perms_by_module[mod].each do |permission| %>
84
            <div class="g_c<%= (even)? " g_e":" g_o" %>" title="<%= "#{l_or_humanize(permission.name, :prefix => 'permission_')} - #{role.name}" %>">
85
              <% even = !even %>
86
              <% if role.setable_permissions.include? permission %>
87
                <%= check_box_tag "permissions[#{role.id}][]", permission.name, (role.permissions.include? permission.name), :id => nil, :class => "role-#{role.id} permission-#{permission.name}" %>
88
              <% else %>
89
                &nbsp;
90
              <% end %>
91
            </div>
74 92
          <% end %>
75 93
        <% end %>
76
        </tr>
94
      </div>
77 95
    <% end %>
78
<% end %>
79
</tbody>
80
</table>
96
  </div>
81 97
</div>
98

  
99
<script> g_adjust('g_bl', 'g_fr', 'g_fl', 'g_bd'); </script>
100

  
82 101
<p><%= check_all_links 'permissions_form' %></p>
83 102
<p><%= submit_tag l(:button_save) %></p>
84 103
<% end %>
app/views/trackers/fields.html.erb
2 2
<% if @trackers.any? %>
3 3
  <%= form_tag fields_trackers_path do %>
4
    <div class="autoscroll">
5
    <table class="list tracker-summary">
6
    <thead>
7
      <tr>
8
        <th></th>
4
    <%= stylesheet_link_tag 'divgrid' %>
5
    <%= javascript_include_tag 'divgrid' %>
6

  
7
    <div style="position: relative; overflow: hidden; white-space: nowrap; border-width: 1px; border-style: solid; border-color: #CCC;">
8
      <!-- Cell 0 -->
9
      <div id="g_bl" style="position: absolute; top: 0px; left: 0px; z-index: 2;">
10
        <div class="g_c g_h">&nbsp;</div>
11
      </div>
12
      <!-- Line 0  -->
13
      <div id="g_fl" class="ibf" style="position: absolute; top: 0px; left: 0px; right: 12px; overflow: hidden; z-index: 1;">
14
        <div style="display: inline-block;">
15
          <div class="g_c">&nbsp;</div>
16
        </div>
9 17
        <% @trackers.each do |tracker| %>
10
        <th>
11
          <%= link_to_function('', "toggleCheckboxesBySelector('input.tracker-#{tracker.id}')",
12
                               :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
13
                               :class => 'icon-only icon-checked') %>
14
          <%= tracker.name %>
15
        </th>
18
          <div style="display: inline-block;">
19
            <div class="g_c g_h">
20
              <%= link_to_function('', "toggleCheckboxesBySelector('input.tracker-#{tracker.id}')",
21
                                   :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
22
                                   :class => 'icon-only icon-checked') %>
23
              <%= tracker.name %>
24
            </div>
25
          </div>
16 26
        <% end %>
17
      </tr>
18
    </thead>
19
    <tbody>
20
      <tr class="group open">
21
        <td colspan="<%= @trackers.size + 1 %>">
22
          <span class="expander icon icon-expended" onclick="toggleRowGroup(this);">&nbsp;</span>
27
      </div>
28
      <!-- Row 0 -->
29
      <div id="g_fr" style="position: absolute; top: 0px; left: 0px; bottom: 12px; overflow: hidden; z-index: 1;">
30
        <div class="g_c">&nbsp;</div>
31
        <% even = false %>
32
        <div class="g_c g_v g_s<%= (even)? " g_e":" g_o" %>">
33
          <% even = !even %>
23 34
          <%= l(:field_core_fields) %>
24
        </td>
25
      </tr>
26
      <% Tracker::CORE_FIELDS.each do |field| %>
27
      <tr>
28
        <% field_name = l("field_#{field}".sub(/_id$/, '')) %>
29
        <td class="name">
30
          <%= link_to_function('', "toggleCheckboxesBySelector('input.core-field-#{field}')",
31
                               :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
32
                               :class => 'icon-only icon-checked') %>
33
          <%= field_name %>
34
        </td>
35
        <% @trackers.each do |tracker| %>
36
        <td title="<%= "#{tracker.name}: #{field_name}" %>">
37
          <%= check_box_tag "trackers[#{tracker.id}][core_fields][]", field, tracker.core_fields.include?(field),
38
                            :class => "tracker-#{tracker.id} core-field-#{field}", :id => nil %>
39
        </td>
40
        <% end %>
41
      </tr>
42
      <% end %>
43
      <% if @custom_fields.any? %>
44
        <tr class="group open">
45
          <td colspan="<%= @trackers.size + 1 %>">
46
            <span class="expander icon icon-expended" onclick="toggleRowGroup(this);">&nbsp;</span>
47
            <%= l(:label_custom_field_plural) %>
48
          </td>
49
        </tr>
50
        <% @custom_fields.each do |field| %>
51
        <tr>
52
          <td class="name">
53
            <%= link_to_function('', "toggleCheckboxesBySelector('input.custom-field-#{field.id}')",
35
        </div>
36
        <% Tracker::CORE_FIELDS.each do |field| %>
37
          <div class="g_c g_v<%= (even)? " g_e":" g_o" %>">
38
            <% even = !even %>
39
            <%= link_to_function('', "toggleCheckboxesBySelector('input.core-field-#{field}')",
54 40
                                 :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
55 41
                                 :class => 'icon-only icon-checked') %>
56
            <%= field.name %>
57
          </td>
58
          <% @trackers.each do |tracker| %>
59
          <td title="<%= "#{tracker.name}: #{field.name}" %>">
42
            <%= l("field_#{field}".sub(/_id$/, '')) %>
43
          </div>
44
        <% end %>
45
        <% if @custom_fields.any? %>
46
          <div class="g_c g_v g_s<%= (even)? " g_e":" g_o" %>">
47
            <% even = !even %>
48
            <%= l(:label_custom_field_plural) %>
49
          </div>
50
          <% @custom_fields.each do |field| %>
51
            <div class="g_c g_v<%= (even)? " g_e":" g_o" %>">
52
              <% even = !even %>
53
              <%= link_to_function('', "toggleCheckboxesBySelector('input.custom-field-#{field.id}')",
54
                                   :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
55
                                   :class => 'icon-only icon-checked') %>
56
              <%= field.name %>
57
            </div>
58
          <% end %>
59
        <% end %>
60
      </div>
61
      <!-- Body -->
62
      <div id="g_bd" class="ibf" style="width: 100%; max-height: 80vh; overflow: scroll;" onscroll="g_scroll(this, 'g_fl', 'g_fr')">
63
        <div style="display: inline-block;"></div>
64
        <% @trackers.each do |tracker| %>
65
        <div style="display: inline-block;">
66
          <div class="g_c">&nbsp;</div>
67
          <% even = false %>
68
          <div class="g_c<%= " g_s" unless tracker == @trackers.last %><%= (even)? " g_e":" g_o" %>"></div>
69
          <% even = !even %>
70
          <% Tracker::CORE_FIELDS.each do |field| %>
71
          <div class="g_c<%= (even)? " g_e":" g_o" %>" title="<%= "#{l("field_#{field}".sub(/_id$/, ''))} - #{tracker}" %>">
72
            <% even = !even %>
73
            <%= check_box_tag "trackers[#{tracker.id}][core_fields][]", field, tracker.core_fields.include?(field),
74
                              :class => "tracker-#{tracker.id} core-field-#{field}", :id => nil %>
75
          </div>
76
          <% end %>
77
          <% if @custom_fields.any? %>
78
          <div class="g_c<%= " g_s" unless tracker == @trackers.last %><%= (even)? " g_e":" g_o" %>"></div>
79
          <% even = !even %>
80
          <% @custom_fields.each do |field| %>
81
          <div class="g_c<%= (even)? " g_e":" g_o" %>" title="<%= "#{field.name} - #{tracker}" %>">
82
            <% even = !even %>
60 83
            <%= check_box_tag "trackers[#{tracker.id}][custom_field_ids][]", field.id, tracker.custom_fields.include?(field),
61 84
                              :class => "tracker-#{tracker.id} custom-field-#{field.id}", :id => nil %>
62
          </td>
85
          </div>
63 86
          <% end %>
64
        </tr>
87
          <% end %>
88
        </div>
65 89
        <% end %>
66
      <% end %>
67
    </tbody>
68
    </table>
90
      </div>
69 91
    </div>
70 92
    <p><%= submit_tag l(:button_save) %></p>
71 93
    <% @trackers.each do |tracker| %>
......
74 96
      <%= hidden_field_tag "trackers[#{tracker.id}][custom_field_ids][]", '' %>
75 97
    <% end %>
76 98
  <% end %>
99

  
100
  <script> g_adjust('g_bl', 'g_fr', 'g_fl', 'g_bd'); </script>
101

  
77 102
<% else %>
78 103
  <p class="nodata"><%= l(:label_no_data) %></p>
79 104
<% end %>
app/views/workflows/_form.html.erb
1
<table class="list workflows transitions transitions-<%= name %>">
2
<thead>
3
  <tr>
4
    <th>
5
      <%= link_to_function('', "toggleCheckboxesBySelector('table.transitions-#{name} input[type=checkbox]:not(:disabled)')",
6
                           :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
7
                           :class => 'icon-only icon-checked') %>
8
      <%=l(:label_current_status)%>
9
    </th>
10
    <th colspan="<%= @statuses.length %>"><%=l(:label_new_statuses_allowed)%></th>
11
  </tr>
12
  <tr>
13
    <td></td>
14
    <% for new_status in @statuses %>
15
    <td style="width:<%= 75 / @statuses.size %>%;">
16
      <%= link_to_function('', "toggleCheckboxesBySelector('table.transitions-#{name} input[type=checkbox]:not(:disabled).new-status-#{new_status.id}')",
17
                           :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
18
                           :class => 'icon-only icon-checked') %>
19
      <%= new_status.name %>
20
    </td>
21
    <% end %>
22
  </tr>
23
</thead>
24 1
<% transition_counts = workflows.each_with_object(Hash.new(0)) {|w,memo| memo[[w.old_status, w.new_status]] += 1} %>
25
<tbody>
2
<!-- Cell 0 -->
3
<div id="g_bl_<%= name %>" style="position: absolute; top: 0px; left: 0px; z-index: 2;">
4
  <div class="g_c g_h">
5
    <%= link_to_function('',
6
      "toggleCheckboxesBySelector('#workflow_#{name} input[type=checkbox]:not(:disabled)')",
7
      :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
8
      :class => 'icon-only icon-checked') %>
9
    <%=l(:label_current_status)%>
10
  </div>
11
</div>
12
<!-- Line 0  -->
13
<div id="g_fl_<%= name %>" class="ibf" style="position: absolute; top: 0px; left: 0px; right: 12px; overflow: hidden; z-index: 1;">
14
  <div style="display: inline-block;">
15
    <div class="g_c">&nbsp;</div>
16
  </div>
17
  <% for new_status in @statuses %>
18
    <div style="display: inline-block;">
19
      <div class="g_c g_h">
20
        <%= link_to_function('',
21
          "toggleCheckboxesBySelector('#workflow_#{name} input[type=checkbox]:not(:disabled).new-status-#{new_status.id}')",
22
          :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
23
          :class => 'icon-only icon-checked') %>
24
        <%= new_status.name %>
25
      </div>
26
    </div>
27
  <% end %>
28
</div>
29
<!-- Row 0 -->
30
<div id="g_fr_<%= name %>" style="position: absolute; top: 0px; left: 0px; bottom: 12px; overflow: hidden; z-index: 1;">
31
  <div class="g_c">&nbsp;</div>
32
  <% even = false %>
26 33
  <% for old_status in [nil] + @statuses %>
27
  <% next if old_status.nil? && name != 'always' %>
28
  <tr>
29
    <td class="name">
30
      <%= link_to_function('', "toggleCheckboxesBySelector('table.transitions-#{name} input[type=checkbox]:not(:disabled).old-status-#{old_status.try(:id) || 0}')",
31
                           :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
32
                           :class => 'icon-only icon-checked') %>
33
      <% if old_status %>
34
        <% old_status_name = old_status.name %>
35
        <%= old_status_name %>
36
      <% else %>
37
        <% old_status_name = l(:label_issue_new) %>
38
        <%= content_tag('em', old_status_name) %>
34
    <% next if old_status.nil? && name != 'always' %>
35
    <div class="g_c g_v<%= (even)? " g_e":" g_o" %>">
36
      <% even = !even %>
37
      <%= link_to_function('',
38
        "toggleCheckboxesBySelector('#workflow_#{name} input[type=checkbox]:not(:disabled).old-status-#{old_status.try(:id) || 0}')",
39
        :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}",
40
        :class => 'icon-only icon-checked') %>
41
      <%= old_status ? old_status.name : content_tag('em', l(:label_issue_new)) %>
42
    </div>
43
  <% end %>
44
</div>
45
<!-- Body -->
46
<div id="g_bd_<%= name %>" class="ibf" style="width: 100%; max-height: 80vh; overflow: scroll;" onscroll="g_scroll(this, 'g_fl_<%= name %>', 'g_fr_<%= name %>')">
47
  <div style="display: inline-block;"></div>
48
  <% for new_status in @statuses %>
49
    <div style="display: inline-block;">
50
      <div class="g_c">&nbsp;</div>
51
      <% even = false %>
52
      <% for old_status in [nil] + @statuses %>
53
        <% next if old_status.nil? && name != 'always' %>
54
        <% checked = (old_status == new_status) || workflows.detect {|w| w.old_status == old_status && w.new_status == new_status} %>
55
        <div class="g_c<%= checked ? " g_m" : (even)? " g_e" : " g_o" %>" title="<%= old_status ? old_status.name : content_tag('em', l(:label_issue_new)) %> &rarr; <%= new_status.name %>">
56
          <% even = !even %>
57
          <%= transition_tag workflows, old_status, new_status, name %>
58
        </div>
39 59
      <% end %>
40
    </td>
41
    <% for new_status in @statuses -%>
42
    <% checked = (old_status == new_status) || workflows.detect {|w| w.old_status == old_status && w.new_status == new_status} %>
43
    <td class="<%= checked ? 'enabled' : '' %>" title="<%= old_status_name %> &#187; <%= new_status.name %>">
44
      <%= transition_tag workflows, old_status, new_status, name %>
45
    </td>
46
    <% end -%>
47
  </tr>
60
    </div>
48 61
  <% end %>
49
</tbody>
50
</table>
62
</div>
app/views/workflows/edit.html.erb
32 32
<% end %>
33 33
<% if @trackers && @roles && @statuses.any? %>
34
  <%= stylesheet_link_tag 'divgrid' %>
35
  <%= javascript_include_tag 'divgrid' %>
36

  
34 37
  <%= form_tag({}, :id => 'workflow_form' ) do %>
35 38
    <%= @trackers.map {|tracker| hidden_field_tag 'tracker_id[]', tracker.id, :id => nil}.join.html_safe %>
36 39
    <%= @roles.map {|role| hidden_field_tag 'role_id[]', role.id, :id => nil}.join.html_safe %>
37 40
    <%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only], :id => nil %>
38 41
    <div class="autoscroll">
39
      <%= render :partial => 'form', :locals => {:name => 'always', :workflows => @workflows['always']} %>
42
      <div id="workflow_always" style="position: relative; overflow: hidden; white-space: nowrap; border-width: 1px; border-style: solid; border-color: #CCC;">
43
        <%= render :partial => 'form', :locals => {:name => 'always', :workflows => @workflows['always']} %>
44
      </div>
40
      <fieldset class="collapsible" style="padding: 0; margin-top: 0.5em;">
41
        <legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_additional_workflow_transitions_for_author) %></legend>
42
        <div id="author_workflows" style="margin: 0.5em 0 0.5em 0;">
43
          <%= render :partial => 'form', :locals => {:name => 'author', :workflows => @workflows['author']} %>
44
        </div>
45
      <fieldset class="collapsible collapsed" style="padding: 0; margin-top: 2em; margin-bottom: 1em;">
46
        <legend onclick="toggleFieldset(this); toggleDivToFieldset('workflow_author',this.parentNode.className);">
47
          <%= l(:label_additional_workflow_transitions_for_author) %>
48
        </legend>
45 49
      </fieldset>
50
      <div id="workflow_author" style="visibility: hidden; position: fixed; top: 0px; overflow: hidden; white-space: nowrap; border-width: 1px; border-style: solid; border-color: #CCC;">
51
        <%= render :partial => 'form', :locals => {:name => 'author', :workflows => @workflows['author']} %>
52
      </div>
46 53
      <%= javascript_tag "hideFieldset($('#author_workflows'))" unless @workflows['author'].present? %>
47
      <fieldset class="collapsible" style="padding: 0;">
48
        <legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_additional_workflow_transitions_for_assignee) %></legend>
49
        <div id="assignee_workflows" style="margin: 0.5em 0 0.5em 0;">
50
      <%= render :partial => 'form', :locals => {:name => 'assignee', :workflows => @workflows['assignee']} %>
51
        </div>
54
      <fieldset class="collapsible collapsed" style="padding: 0; margin-top: 2em; margin-bottom: 1em;">
55
        <legend onclick="toggleFieldset(this);toggleDivToFieldset('workflow_assignee',this.parentNode.className);">
56
          <%= l(:label_additional_workflow_transitions_for_assignee) %>
57
        </legend>
52 58
      </fieldset>
59
      <div id="workflow_assignee" style="visibility: hidden; position: fixed; top: 0px; overflow: hidden; white-space: nowrap; border-width: 1px; border-style: solid; border-color: #CCC;">
60
        <%= render :partial => 'form', :locals => {:name => 'assignee', :workflows => @workflows['assignee']} %>
61
      </div>
53 62
      <%= javascript_tag "hideFieldset($('#assignee_workflows'))" unless @workflows['assignee'].present? %>
63

  
64
      <script> g_adjust('g_bl_always', 'g_fr_always', 'g_fl_always', 'g_bd_always'); </script>
65
      <script> g_adjust('g_bl_author', 'g_fr_author', 'g_fl_author', 'g_bd_author'); </script>
66
      <script> g_adjust('g_bl_assignee', 'g_fr_assignee', 'g_fl_assignee', 'g_bd_assignee'); </script>
54 67
    </div>
55 68
    <%= submit_tag l(:button_save) %>
56 69
  <% end %>
app/views/workflows/index.html.erb
1 1
<%= title [l(:label_workflow), workflows_edit_path], l(:field_summary) %>
2 2
<% if @roles.empty? || @trackers.empty? %>
3
<p class="nodata"><%= l(:label_no_data) %></p>
3
  <p class="nodata"><%= l(:label_no_data) %></p>
4 4
<% else %>
5
<div class="autoscroll">
6
<table class="list">
7
<thead>
8
    <tr>
9
    <th></th>
10
    <% @roles.each do |role| %>
11
    <th>
12
        <%= content_tag(role.builtin? ? 'em' : 'span', role.name) %>
13
    </th>
14
    <% end %>
15
    </tr>
16
</thead>
17
<tbody>
18
<% @trackers.each do |tracker| -%>
19
<tr>
20
  <td class="name"><%= tracker.name %></td>
21
  <% @roles.each do |role| -%>
22
  <% count = @workflow_counts[[tracker.id, role.id]] || 0 %>
23
    <td>
24
      <%= link_to((count > 0 ? count : content_tag(:span, nil, :class => 'icon-only icon-not-ok')),
25
                  {:action => 'edit', :role_id => role, :tracker_id => tracker},
26
                  :title => l(:button_edit)) %>
27
    </td>
28
  <% end -%>
29
</tr>
30
<% end -%>
31
</tbody>
32
</table>
33
</div>
5
  <%= stylesheet_link_tag 'divgrid' %>
6
  <%= javascript_include_tag 'divgrid' %>
7

  
8
  <div style="position: relative; overflow: hidden; white-space: nowrap; border-width: 1px; border-style: solid; border-color: #CCC;">
9
    <!-- Cell 0 -->
10
    <div id="g_bl" style="position: absolute; top: 0px; left: 0px; z-index: 2;">
11
      <div class="g_c g_h">&nbsp;</div>
12
    </div>
13
    <!-- Line 0  -->
14
    <div id="g_fl" class="ibf" style="position: absolute; top: 0px; left: 0px; right: 12px; overflow: hidden; z-index: 1;">
15
      <div style="display: inline-block;">
16
        <div class="g_c">&nbsp;</div>
17
      </div>
18
      <% @roles.each do |role| %>
19
        <div style="display: inline-block;">
20
          <div class="g_c g_h">
21
            <%= role.name %>
22
          </div>
23
        </div>
24
      <% end %>
25
    </div>
26
    <!-- Row 0 -->
27
    <div id="g_fr" style="position: absolute; top: 0px; left: 0px; bottom: 12px; overflow: hidden; z-index: 1;">
28
      <div class="g_c">&nbsp;</div>
29
      <% even = false %>
30
      <% @trackers.each do |tracker| %>
31
        <div class="g_c g_v<%= (even)? " g_e":" g_o" %>">
32
          <% even = !even %>
33
          <%= tracker.name %>
34
        </div>
35
      <% end %>
36
    </div>
37
    <!-- Body -->
38
    <div id="g_bd" class="ibf" style="width: 100%; max-height: 80vh; overflow: scroll;" onscroll="g_scroll(this, 'g_fl', 'g_fr')">
39
      <div style="display: inline-block;"></div>
40
      <% @roles.each do |role| %>
41
        <div style="display: inline-block;">
42
          <div class="g_c">&nbsp;</div>
43
          <% even = false %>
44
          <% @trackers.each do |tracker| %>
45
            <% count = @workflow_counts[[tracker.id, role.id]] || 0 %>
46
            <div class="g_c<%= (even)? " g_e":" g_o" %>" title="<%= "#{tracker} - #{role}" %>">
47
              <% even = !even %>
48
              <%= link_to((count > 0 ? count : content_tag(:span, nil, :class => 'icon-only icon-not-ok')),
49
                          {:action => 'edit', :role_id => role, :tracker_id => tracker},
50
                          :title => l(:button_edit)) %>
51
            </div>
52
          <% end %>
53
        </div>
54
      <% end %>
55
    </div>
56
  </div>
57

  
58
  <script> g_adjust('g_bl', 'g_fr', 'g_fl', 'g_bd'); </script>
59

  
34 60
<% end %>
app/views/workflows/permissions.html.erb
31 31
<% end %>
32 32
<% if @trackers && @roles && @statuses.any? %>
33
  <%= stylesheet_link_tag 'divgrid' %>
34
  <%= javascript_include_tag 'divgrid' %>
35

  
33 36
  <%= form_tag({}, :id => 'workflow_form' ) do %>
34 37
    <%= @trackers.map {|tracker| hidden_field_tag 'tracker_id[]', tracker.id, :id => nil}.join.html_safe %>
35 38
    <%= @roles.map {|role| hidden_field_tag 'role_id[]', role.id, :id => nil}.join.html_safe %>
36 39
    <%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only], :id => nil %>
37 40
    <div class="autoscroll">
38
    <table class="list workflows fields_permissions">
39
    <thead>
40
      <tr>
41
        <th>
42
        </th>
43
        <th colspan="<%= @statuses.length %>"><%=l(:label_issue_status)%></th>
44
      </tr>
45
      <tr>
46
        <td></td>
47
        <% for status in @statuses %>
48
        <td style="width:<%= 75 / @statuses.size %>%;">
49
          <%= status.name %>
50
        </td>
51
        <% end %>
52
      </tr>
53
    </thead>
54
    <tbody>
55
      <tr class="group open">
56
        <td colspan="<%= @statuses.size + 1 %>">
57
          <span class="expander icon icon-expended" onclick="toggleRowGroup(this);">&nbsp;</span>
41
      <fieldset class="collapsible" style="padding: 0; margin-top: 2em; margin-bottom: 1em;">
42
        <legend style="padding-left: 0; background: none;">
58 43
          <%= l(:field_core_fields) %>
59
        </td>
60
      </tr>
61
      <% @fields.each do |field, name| %>
62
      <tr>
63
        <td class="name">
64
          <%= name %> <%= content_tag('span', '*', :class => 'required') if field_required?(field) %>
65
        </td>
66
        <% for status in @statuses -%>
67
        <td class="<%= @permissions[status.id][field].try(:join, ' ') %>" title="<%= name %> (<%= status.name %>)">
68
          <%= field_permission_tag(@permissions, status, field, @roles) %>
69
          <% unless status == @statuses.last %><a href="#" class="repeat-value">&#187;</a><% end %>
70
        </td>
71
        <% end -%>
72
      </tr>
73
      <% end %>
44
        </legend>
45
      </fieldset>
46
      <div id='default_fields' style="position: relative; overflow: hidden; white-space: nowrap; border-width: 1px; border-style: solid; border-color: #CCC;">
47
        <!-- Cell 0 -->
48
        <div id="g_bla" style="position: absolute; top: 0px; left: 0px; z-index: 2;">
49
          <div class="g_c g_h">&nbsp;</div>
50
        </div>
51
        <!-- Line 0  -->
52
        <div id="g_fla" class="ibf" style="position: absolute; top: 0px; left: 0px; right: 12px; overflow: hidden; z-index: 1;">
53
          <div style="display: inline-block;">
54
            <div class="g_c">&nbsp;</div>
55
          </div>
56
          <% for status in @statuses %>
57
            <div style="display: inline-block;">
58
              <div class="g_c g_h">
59
                <%= status.name %>
60
              </div>
61
            </div>
62
          <% end %>
63
        </div>
64
        <!-- Row 0 -->
65
        <div id="g_fra" style="position: absolute; top: 0px; left: 0px; bottom: 12px; overflow: hidden; z-index: 1;">
66
          <div class="g_c">&nbsp;</div>
67
          <% even = false %>
68
          <% @fields.each do |field, name| %>
69
            <div class="g_c g_v<%= (even)? " g_e":" g_o" %>">
70
              <% even = !even %>
71
              <%= name %> <%= content_tag('span', '*', :class => 'required') if field_required?(field) %>
72
            </div>
73
          <% end %>
74
        </div>
75
        <!-- Body -->
76
        <div id="g_bda" class="ibf" style="width: 100%; max-height: 80vh; overflow: scroll;" onscroll="g_scroll(this, 'g_fla', 'g_fra')">
77
          <div style="display: inline-block;"></div>
78
          <% for status in @statuses %>
79
            <div style="display: inline-block;">
80
              <div class="g_c">&nbsp;</div>
81
              <% even = false %>
82
              <% @fields.each do |field, name| %>
83
                <div class="g_c<%= (even)? " g_e" : " g_o" %> <%= @permissions[status.id][field].try(:join, ' ') %>" title="<%= name %> (<%= status.name %>)">
84
                  <div style="margin-top: -5px;" >
85
                    <% even = !even %>
86
                    <%= field_permission_tag(@permissions, status, field, @roles) %>
87
                    <% unless status == @statuses.last %><a href="#" class="repeat-value">&#187;</a><% end %>
88
                  </div>
89
                </div>
90
              <% end %>
91
            </div>
92
          <% end %>
93
        </div>
94
      </div>
95

  
74 96
      <% if @custom_fields.any? %>
75
        <tr class="group open">
76
          <td colspan="<%= @statuses.size + 1 %>">
77
            <span class="expander icon icon-expended" onclick="toggleRowGroup(this);">&nbsp;</span>
97
        <fieldset class="collapsible" style="padding: 0; margin-top: 2em; margin-bottom: 1em;">
98
          <legend onclick="toggleFieldset(this);toggleDivToFieldset('personal_fields',this.parentNode.className);">
78 99
            <%= l(:label_custom_field_plural) %>
79
          </td>
80
        </tr>
81
        <% @custom_fields.each do |field| %>
82
        <tr>
83
          <td class="name">
84
            <%= field.name %> <%= content_tag('span', '*', :class => 'required') if field_required?(field) %>
85
          </td>
86
          <% for status in @statuses -%>
87
          <td class="<%= @permissions[status.id][field.id.to_s].try(:join, ' ') %>" title="<%= field.name %> (<%= status.name %>)">
88
            <%= field_permission_tag(@permissions, status, field, @roles) %>
89
            <% unless status == @statuses.last %><a href="#" class="repeat-value">&#187;</a><% end %>
90
          </td>
91
          <% end -%>
92
        </tr>
93
        <% end %>
94
      <% end %>
95
    </tbody>
96
    </table>
100
          </legend>
101
        </fieldset>
102
        <div id='personal_fields' style="position: relative; overflow: hidden; white-space: nowrap; border-width: 1px; border-style: solid; border-color: #CCC;">
103
          <!-- Cell 0 -->
104
          <div id="g_blb" style="position: absolute; top: 0px; left: 0px; z-index: 2;">
105
            <div class="g_c g_h">&nbsp;</div>
106
          </div>
107
          <!-- Line 0  -->
108
          <div id="g_flb" class="ibf" style="position: absolute; top: 0px; left: 0px; right: 12px; overflow: hidden; z-index: 1;">
109
            <div style="display: inline-block;">
110
              <div class="g_c">&nbsp;</div>
111
            </div>
112
            <% for status in @statuses %>
113
              <div style="display: inline-block;">
114
                <div class="g_c g_h">
115
                  <%= status.name %>
116
                </div>
117
              </div>
118
            <% end %>
119
          </div>
120
          <!-- Row 0 -->
121
          <div id="g_frb" style="position: absolute; top: 0px; left: 0px; bottom: 12px; overflow: hidden; z-index: 1;">
122
            <div class="g_c">&nbsp;</div>
123
            <% even = false %>
124
            <% @custom_fields.each do |field| %>
125
              <div class="g_c g_v<%= (even)? " g_e":" g_o" %>">
126
                <% even = !even %>
127
                <%= field.name %> <%= content_tag('span', '*', :class => 'required') if field_required?(field) %>
128
              </div>
129
            <% end %>
130
          </div>
131
          <!-- Body -->
132
          <div id="g_bdb" class="ibf" style="width: 100%; max-height: 80vh; overflow: scroll;" onscroll="g_scroll(this, 'g_flb', 'g_frb')">
133
            <div style="display: inline-block;"></div>
134
            <% for status in @statuses %>
135
              <div style="display: inline-block;">
136
                <div class="g_c">&nbsp;</div>
137
                <% even = false %>
138
                <% @custom_fields.each do |field| %>
139
                  <div class="g_c<%= (even)? " g_e" : " g_o" %> <%= @permissions[status.id][field.id.to_s].try(:join, ' ') %>" title="<%= field.name %> (<%= status.name %>)">
140
                    <div style="margin-top: -5px;" >
141
                      <% even = !even %>
142
                      <%= field_permission_tag(@permissions, status, field, @roles) %>
143
                      <% unless status == @statuses.last %><a href="#" class="repeat-value">&#187;</a><% end %>
144
                    </div>
145
                  </div>
146
                <% end %>
147
              </div>
148
            <% end %>
149
          </div>
150
        </div>
151
      <% end -%>
152
      <script> g_adjust('g_bla', 'g_fra', 'g_fla', 'g_bda'); </script>
153
      <script> g_adjust('g_blb', 'g_frb', 'g_flb', 'g_bdb'); </script>
97 154
    </div>
98 155
    <%= submit_tag l(:button_save) %>
99 156
  <% end %>
......
103 160
<%= javascript_tag do %>
104 161
$("a.repeat-value").click(function(e){
105 162
  e.preventDefault();
106
  var td = $(this).closest('td');
107
  var selected = td.find("select").find(":selected").val();
108
  td.nextAll('td').find("select").val(selected);
163
  var div = $(this).closest('div.g_c');
164
  var selected = div.find("select").find(":selected").val();
165
  var index = div.index() + 1;
166
  div.parent().nextAll('div').find(":nth-child(" + index + ") select").val(selected);
109 167
});
110 168
$("a[data-expands]").click(function(e){
public/javascripts/divgrid.js
1
/* Simple Grid Scripts tables with fixed First Row and Line */
2

  
3
// scrolls first line and row with body
4
// div is this
5
// row is id of row Ex: g_fr
6
// line is id of line Ex: g_fl
7
function g_scroll(div, line, row) {
8
  document.getElementById(line).style.left = - div.scrollLeft + 'px';
9
  document.getElementById(row).style.top = - div.scrollTop + 'px';
10
}
11

  
12
// adjusts width of rows
13
// bli is the block div
14
// fri is the first row div
15
// fli is the first line div
16
// bdi is the body div
17
function g_adjust(bli, fri, fli, bdi) {
18
  var frw = document.getElementById(fri).offsetWidth;
19
  var frw2 = document.getElementById(bli).offsetWidth;
20
  if ( frw2 > frw ) {
21
    frw = frw2 + "px"
22
  } else {
23
    frw = frw + "px";
24
  }
25

  
26
  document.getElementById(fri).style.width = frw;
27
  document.getElementById(bli).style.width = frw;
28

  
29
  var fl = document.getElementById(fli);
30
  fl.children[0].style.width = frw;
31

  
32
  var bd = document.getElementById(bdi);
33
  bd.children[0].style.width = frw;
34

  
35
  for (var i = 1; i < fl.children.length; i++) {
36
    s1 = fl.children[i].offsetWidth;
37
    s2 = bd.children[i].offsetWidth;
38
    if (s1 > s2) {
39
      bd.children[i].style.width = s1 + "px"
40
    } else {
41
      fl.children[i].style.width = s2 + "px"
42
    }
43
  }
44
}
45

  
46
// Toggle visibility of table
47
function toggleDivToFieldset(divId, fsClass) {
48
  if (~fsClass.indexOf("collapsed")) {
49
    document.getElementById(divId).style.visibility='hidden';
50
    document.getElementById(divId).style.position='fixed';
51
  } else {
52
    document.getElementById(divId).style.visibility='';
53
    document.getElementById(divId).style.position='relative';
54
    document.getElementById(divId).children[1].style.left='0px';
55
  }
56
}
public/stylesheets/divgrid.css
1
/* Simple Grid Styles for tables with fixed First Row and Line */
2

  
3
/* Cell */
4
.g_c { height: 1.5em;
5
       padding: 6px;
6
       font-size: 12px;
7
       border-width: 0px 1px 1px 0px;
8
       border-style: solid;
9
       border-color: #CCC;
10
       text-align: center; }
11

  
12
/* First Line */
13
.g_h { background-color: #EEE;
14
       text-align: center; }
15

  
16
/* First Row */
17
.g_v { text-align: left; }
18

  
19
/* Image in Cell */
20
.g_i { height: 16px;
21
       width: 16px;
22
       margin: 0 auto; }
23

  
24
/* Separation Lines */
25
.g_s { font-weight: bold;
26
       border-right: 0px; }
27

  
28
/* Marked Cell */
29
.g_m { background-color: #BFB; }
30

  
31
/* Even Cell */
32
.g_e { background-color: #F6F7F8; }
33

  
34
/* Odd Cell */
35
.g_o { background-color: #FFFFFF; }
36

  
37
/* Inline Block Fix */
38
.ibf { font-size: 0; }
0
-