Project

General

Profile

Patch #20287 » trunk-r19977.patch

Mizuki ISHIKAWA, 2020-08-17 10:41

View differences:

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

  
31
<%= stylesheet_link_tag 'divgrid' %>
32
<%= javascript_include_tag 'divgrid' %>
33

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

  
102
<script> g_adjust('g_bl', 'g_fr', 'g_fl', 'g_bd'); </script>
103

  
85 104
<p><%= check_all_links 'permissions_form' %></p>
86 105
<p><%= submit_tag l(:button_save) %></p>
87 106
<% end %>
app/views/trackers/fields.html.erb
2 2

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

  
34 34
<% if @trackers && @roles && @statuses.any? %>
35
  <%= stylesheet_link_tag 'divgrid' %>
36
  <%= javascript_include_tag 'divgrid' %>
37

  
35 38
  <%= form_tag({}, :id => 'workflow_form' ) do %>
36 39
    <%= @trackers.map {|tracker| hidden_field_tag 'tracker_id[]', tracker.id, :id => nil}.join.html_safe %>
37 40
    <%= @roles.map {|role| hidden_field_tag 'role_id[]', role.id, :id => nil}.join.html_safe %>
38 41
    <%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only], :id => nil %>
39 42
    <div class="autoscroll">
40
      <%= render :partial => 'form', :locals => {:name => 'always', :workflows => @workflows['always']} %>
43
      <div id="workflow_always" style="position: relative; overflow: hidden; white-space: nowrap; border-width: 1px; border-style: solid; border-color: #CCC;">
44
        <%= render :partial => 'form', :locals => {:name => 'always', :workflows => @workflows['always']} %>
45
      </div>
41 46

  
42
      <fieldset class="collapsible" style="padding: 0; margin-top: 0.5em;">
43
        <legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_additional_workflow_transitions_for_author) %></legend>
44
        <div id="author_workflows" style="margin: 0.5em 0 0.5em 0;">
45
          <%= render :partial => 'form', :locals => {:name => 'author', :workflows => @workflows['author']} %>
46
        </div>
47
      <fieldset class="collapsible collapsed" style="padding: 0; margin-top: 2em; margin-bottom: 1em;">
48
        <legend class="expander icon icon-collapsed" onclick="toggleFieldset(this); toggleDivToFieldset('workflow_author',this.parentNode.className);">
49
          <%= l(:label_additional_workflow_transitions_for_author) %>
50
        </legend>
47 51
      </fieldset>
52
      <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;">
53
        <%= render :partial => 'form', :locals => {:name => 'author', :workflows => @workflows['author']} %>
54
      </div>
48 55
      <%= javascript_tag "hideFieldset($('#author_workflows'))" unless @workflows['author'].present? %>
49 56

  
50
      <fieldset class="collapsible" style="padding: 0;">
51
        <legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_additional_workflow_transitions_for_assignee) %></legend>
52
        <div id="assignee_workflows" style="margin: 0.5em 0 0.5em 0;">
53
      <%= render :partial => 'form', :locals => {:name => 'assignee', :workflows => @workflows['assignee']} %>
54
        </div>
57
      <fieldset class="collapsible collapsed" style="padding: 0; margin-top: 2em; margin-bottom: 1em;">
58
        <legend class="expander icon icon-collapsed" onclick="toggleFieldset(this);toggleDivToFieldset('workflow_assignee',this.parentNode.className);">
59
          <%= l(:label_additional_workflow_transitions_for_assignee) %>
60
        </legend>
55 61
      </fieldset>
62
      <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;">
63
        <%= render :partial => 'form', :locals => {:name => 'assignee', :workflows => @workflows['assignee']} %>
64
      </div>
56 65
      <%= javascript_tag "hideFieldset($('#assignee_workflows'))" unless @workflows['assignee'].present? %>
66

  
67
      <script> g_adjust('g_bl_always', 'g_fr_always', 'g_fl_always', 'g_bd_always'); </script>
68
      <script> g_adjust('g_bl_author', 'g_fr_author', 'g_fl_author', 'g_bd_author'); </script>
69
      <script> g_adjust('g_bl_assignee', 'g_fr_assignee', 'g_fl_assignee', 'g_bd_assignee'); </script>
57 70
    </div>
58 71
    <%= submit_tag l(:button_save) %>
59 72
  <% end %>
app/views/workflows/index.html.erb
1 1
<%= title [l(:label_workflow), workflows_edit_path], l(:field_summary) %>
2 2

  
3 3
<% if @roles.empty? || @trackers.empty? %>
4
<p class="nodata"><%= l(:label_no_data) %></p>
4
  <p class="nodata"><%= l(:label_no_data) %></p>
5 5
<% else %>
6
<div class="autoscroll">
7
<table class="list">
8
<thead>
9
    <tr>
10
    <th></th>
11
    <% @roles.each do |role| %>
12
    <th>
13
        <%= content_tag(role.builtin? ? 'em' : 'span', role.name) %>
14
    </th>
15
    <% end %>
16
    </tr>
17
</thead>
18
<tbody>
19
<% @trackers.each do |tracker| -%>
20
<tr>
21
  <td class="name"><%= tracker.name %></td>
22
  <% @roles.each do |role| -%>
23
  <% count = @workflow_counts[[tracker.id, role.id]] || 0 %>
24
    <td>
25
      <%= link_to((count > 0 ? count : content_tag(:span, nil, :class => 'icon-only icon-not-ok')),
26
                  {:action => 'edit', :role_id => role, :tracker_id => tracker},
27
                  :title => l(:button_edit)) %>
28
    </td>
29
  <% end -%>
30
</tr>
31
<% end -%>
32
</tbody>
33
</table>
34
</div>
6
  <%= stylesheet_link_tag 'divgrid' %>
7
  <%= javascript_include_tag 'divgrid' %>
8

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

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

  
35 61
<% end %>
app/views/workflows/permissions.html.erb
15 15
<p>
16 16
  <label><%=l(:label_role)%>:
17 17
  <%= options_for_workflow_select 'role_id[]', Role.sorted.select(&:consider_workflow?), @roles, :id => 'role_id', :class => 'expandable' %>
18
  <span class="toggle-multiselect icon-only"></span>
18
  <a href="#" data-expands="#role_id"><span class="toggle-multiselect icon-only icon-toggle-plus"></span></a>
19 19
  </label>
20 20

  
21 21
  <label><%=l(:label_tracker)%>:
22 22
  <%= options_for_workflow_select 'tracker_id[]', Tracker.sorted, @trackers, :id => 'tracker_id', :class => 'expandable' %>
23
  <span class="toggle-multiselect icon-only"></span>
23
  <a href="#" data-expands="#tracker_id"><span class="toggle-multiselect icon-only icon-toggle-plus"></span></a>
24 24
  </label>
25 25
  <%= submit_tag l(:button_edit), :name => nil %>
26 26

  
......
30 30
<% end %>
31 31

  
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 class="expander icon icon-collapsed" 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" title="<%= l(:button_copy) %>">&#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 class="expander icon icon-collapsed" 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 %>
......
102 159
<%= javascript_tag do %>
103 160
$("a.repeat-value").click(function(e){
104 161
  e.preventDefault();
105
  var td = $(this).closest('td');
106
  var selected = td.find("select").find(":selected").val();
107
  td.nextAll('td').find("select").val(selected);
162
  var div = $(this).closest('div.g_c');
163
  var selected = div.find("select").find(":selected").val();
164
  var index = div.index() + 1;
165
  div.parent().nextAll('div').find(":nth-child(" + index + ") select").val(selected);
166
});
167

  
168
$("a[data-expands]").click(function(e){
169
  e.preventDefault();
170
  var target = $($(this).attr("data-expands"));
171
  if (target.attr("multiple")) {
172
    $(this).find('span').switchClass('icon-toggle-minus', 'icon-toggle-plus');
173
    target.attr("multiple", false);
174
    target.find("option[value=all]").show();
175
  } else {
176
    $(this).find('span').switchClass('icon-toggle-plus', 'icon-toggle-minus');
177
    target.attr("multiple", true);
178
    target.find("option[value=all]").attr("selected", false).hide();
179
  }
108 180
});
109 181
<% end %>
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; }
(13-13/18)