Project

General

Profile

Feature #12005 » workflow_hidden_field_DR_v0.04.patch

David Robinson, 2012-10-30 17:31

View differences:

app/helpers/issues_helper.rb (working copy)
146 146
  end
147 147

  
148 148
  def render_custom_fields_rows(issue)
149
    return if issue.custom_field_values.empty?
149
    local_viewablecf=issue.viewable_custom_field_values
150
    return if local_viewablecf.empty?
150 151
    ordered_values = []
151
    half = (issue.custom_field_values.size / 2.0).ceil
152
    half = (local_viewablecf.size / 2.0).ceil
152 153
    half.times do |i|
153
      ordered_values << issue.custom_field_values[i]
154
      ordered_values << issue.custom_field_values[i + half]
154
      ordered_values << local_viewablecf[i]
155
      ordered_values << local_viewablecf[i + half]
155 156
    end
156 157
    s = "<tr>\n"
157 158
    n = 0
......
221 222
    strings = []
222 223
    values_by_field = {}
223 224
    details.each do |detail|
225
      unless detail.journal.issue.hidden_attribute?(detail.prop_key)
224 226
      if detail.property == 'cf'
225 227
        field_id = detail.prop_key
226 228
        field = CustomField.find_by_id(field_id)
......
237 239
      end
238 240
      strings << show_detail(detail, no_html, options)
239 241
    end
242
    end
240 243
    values_by_field.each do |field_id, changes|
244
      unless detail.journal.issue.hidden_attribute?(detail.prop_key)
241 245
      detail = JournalDetail.new(:property => 'cf', :prop_key => field_id)
242 246
      if changes[:added].any?
243 247
        detail.value = changes[:added]
......
246 250
        detail.old_value = changes[:deleted]
247 251
        strings << show_detail(detail, no_html, options)
248 252
      end
253
      end	
249 254
    end
250 255
    strings
251 256
  end
......
381 386
      # csv lines
382 387
      issues.each do |issue|
383 388
        col_values = columns.collect do |column|
389
	        hidden_fields = issue.hidden_attribute_names.map {|field| field.sub(/_id$/, '')}
390
	        if hidden_fields.include?(column.is_a?(QueryCustomFieldColumn) ? column.custom_field.id.to_s : column.name.to_s)  
391
            ""
392
          else
384 393
          s = if column.is_a?(QueryCustomFieldColumn)
385 394
            cv = issue.custom_field_values.detect {|v| v.custom_field_id == column.custom_field.id}
386 395
            show_value(cv)
......
398 407
          end
399 408
          s.to_s
400 409
        end
410
        end
401 411
        csv << [ issue.id.to_s ] + col_values.collect {|c| Redmine::CodesetUtil.from_utf8(c.to_s, encoding) } +
402 412
          (options[:description] ? [Redmine::CodesetUtil.from_utf8(issue.description, encoding)] : [])
403 413
      end
app/models/issue.rb (working copy)
446 446
    end
447 447
  end
448 448

  
449
  # Returns the custom_field_values that can be viewed by the given user
450
  # For now: just exclude Fix Info and RNs, as it is printed seperately below description.
451
  def viewable_custom_field_values(user=nil)
452
    custom_field_values.reject do |value|
453
      hidden_attribute_names(user).include?(value.custom_field_id.to_s)
454
    end
455
  end
456

  
449 457
  # Returns the names of attributes that are read-only for user or the current user
450 458
  # For users with multiple roles, the read-only fields are the intersection of
451 459
  # read-only fields of each role
......
455 463
  #   issue.read_only_attribute_names # => ['due_date', '2']
456 464
  #   issue.read_only_attribute_names(user) # => []
457 465
  def read_only_attribute_names(user=nil)
458
    workflow_rule_by_attribute(user).reject {|attr, rule| rule != 'readonly'}.keys
466
    workflow_rule_by_attribute(user).reject {|attr, rule| rule != 'readonly' and rule != 'hidden'}.keys
459 467
  end
460 468

  
469
  # Same as above, but for hidden fields
470
  def hidden_attribute_names(user=nil)
471
    workflow_rule_by_attribute(user).reject {|attr, rule| rule != 'hidden'}.keys
472
  end
473

  
461 474
  # Returns the names of required attributes for user or the current user
462 475
  # For users with multiple roles, the required fields are the intersection of
463 476
  # required fields of each role
......
475 488
    required_attribute_names(user).include?(name.to_s)
476 489
  end
477 490

  
491
  # Returns true if the attribute should be hidden for user
492
  def hidden_attribute?(name, user=nil)
493
    logger.info("For " + name.to_s + ", It will return " + hidden_attribute_names(user).include?(name.to_s).to_s )
494
#    hidden_attribute_names(user).each do |n|
495
#      logger.info(n.to_s)
496
#    end    
497
    hidden_attribute_names(user).include?(name.to_s)
498
  end
499

  
500

  
478 501
  # Returns a hash of the workflow rule by attribute for the given user
479 502
  #
480 503
  # Examples:
app/models/project.rb (working copy)
146 146
    user.allowed_to?(:view_project, self)
147 147
  end
148 148

  
149
  # Returns list of attributes that are hidden on all statuses of all trackers for +user+ or the current user.
150
  def completely_hidden_attribute_names(user=nil)
151
    user_real = user || User.current
152
    roles = user_real.admin ? Role.all : user_real.roles_for_project(self)
153
    return {} if roles.empty?
154

  
155
    result = {}
156
    workflow_permissions = WorkflowPermission.where(:tracker_id => trackers.map(&:id), :old_status_id => IssueStatus.all.map(&:id), :role_id => roles.map(&:id), :rule => 'hidden').all
157

  
158
    if workflow_permissions.any?
159
      workflow_rules = workflow_permissions.inject({}) do |h, wp|
160
        h[wp.field_name] ||= []
161
        h[wp.field_name] << wp.rule
162
        h
163
      end
164
      workflow_rules.each do |attr, rules|
165
        next if rules.size < (roles.size * trackers.size * IssueStatus.all.size)
166
        uniq_rules = rules.uniq
167
        if uniq_rules.size == 1
168
          result[attr] = uniq_rules.first
169
        else
170
          result[attr] = 'required'
171
        end
172
      end
173
    end
174

  
175
    result.keys    
176
  end
177

  
178

  
149 179
  # Returns a SQL conditions string used to find all projects visible by the specified user.
150 180
  #
151 181
  # Examples:
app/models/query.rb (working copy)
44 44
  end
45 45

  
46 46
  def value(issue)
47
    hidden_fields = issue.hidden_attribute_names.map {|field| field.sub(/_id$/, '')}
48
    if hidden_fields.include?(name.to_s)
49
      ""
50
    else
47 51
    issue.send name
48 52
  end
53
  end
49 54

  
50 55
  def css_classes
51 56
    name
......
360 365
    Tracker.disabled_core_fields(trackers).each {|field|
361 366
      @available_filters.delete field
362 367
    }
368

  
369
    project.completely_hidden_attribute_names.each {|field|
370
      @available_filters.delete field
371
    }
372

  
363 373
    @available_filters.each do |field, options|
364 374
      options[:name] ||= l(options[:label] || "field_#{field}".gsub(/_id$/, ''))
365 375
    end
......
451 461
  def available_columns
452 462
    return @available_columns if @available_columns
453 463
    @available_columns = ::Query.available_columns.dup
464

  
465
    hidden_fields = project.completely_hidden_attribute_names.map {|field| field.sub(/_id$/, '')}
466

  
454 467
    @available_columns += (project ?
455 468
                            project.all_issue_custom_fields :
456 469
                            IssueCustomField.find(:all)
457
                           ).collect {|cf| QueryCustomFieldColumn.new(cf) }
470
                           ).collect {|cf| QueryCustomFieldColumn.new(cf) }.reject{|column| hidden_fields.include?(column.custom_field.id.to_s) }
458 471

  
459 472
    if User.current.allowed_to?(:view_time_entries, project, :global => true)
460 473
      index = nil
......
477 490
    @available_columns.reject! {|column|
478 491
      disabled_fields.include?(column.name.to_s)
479 492
    }
493
    
494
    @available_columns.reject! {|column|
495
      hidden_fields.include?(column.name.to_s)
496
    }
480 497

  
481 498
    @available_columns
482 499
  end
......
966 983
    @available_filters ||= {}
967 984

  
968 985
    custom_fields.select(&:is_filter?).each do |field|
986
      unless project.completely_hidden_attribute_names.include?(field.id.to_s)
969 987
      case field.field_format
970 988
      when "text"
971 989
        options = { :type => :text, :order => 20 }
......
1002 1020
             })
1003 1021
    end
1004 1022
  end
1023
  end
1005 1024

  
1006 1025
  def add_associations_custom_fields_filters(*associations)
1007 1026
    fields_by_class = CustomField.where(:is_filter => true).group_by(&:class)
app/views/issues/_form_custom_fields.html.erb (working copy)
1 1
<div class="splitcontent">
2 2
<div class="splitcontentleft">
3 3
<% i = 0 %>
4
<% split_on = (@issue.custom_field_values.size / 2.0).ceil - 1 %>
4
<% split_on = (@issue.editable_custom_field_values.size / 2.0).ceil - 1 %>
5 5
<% @issue.editable_custom_field_values.each do |value| %>
6 6
  <p><%= custom_field_tag_with_label :issue, value, :required => @issue.required_attribute?(value.custom_field_id) %></p>
7 7
<% if i == split_on -%>
app/views/issues/_history.html.erb (working copy)
1 1
<% reply_links = authorize_for('issues', 'edit') -%>
2 2
<% for journal in journals %>
3
  <% if details_to_strings(journal.details).any? || journal.notes.blank? == false %>
3 4
  <div id="change-<%= journal.id %>" class="<%= journal.css_classes %>">
4 5
    <div id="note-<%= journal.indice %>">
5 6
    <h4><%= link_to "##{journal.indice}", {:anchor => "note-#{journal.indice}"}, :class => "journal-link" %>
6 7
    <%= avatar(journal.user, :size => "24") %>
7 8
    <%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %></h4>
8

  
9
  
9 10
    <% if journal.details.any? %>
10 11
    <ul class="details">
11 12
      <% details_to_strings(journal.details).each do |string| %>
......
17 18
    </div>
18 19
  </div>
19 20
  <%= call_hook(:view_issues_history_journal_bottom, { :journal => journal }) %>
21
  <% end %>
20 22
<% end %>
21 23

  
22 24
<% heads_for_wiki_formatter if User.current.allowed_to?(:edit_issue_notes, issue.project) || User.current.allowed_to?(:edit_own_issue_notes, issue.project) %>
app/views/issues/show.html.erb (working copy)
33 33

  
34 34
<table class="attributes">
35 35
<%= issue_fields_rows do |rows|
36
  unless @issue.hidden_attribute?('status')
36 37
  rows.left l(:field_status), h(@issue.status.name), :class => 'status'
38
  end
39
  unless @issue.hidden_attribute?('priority')
37 40
  rows.left l(:field_priority), h(@issue.priority.name), :class => 'priority'
41
  end
38 42

  
39
  unless @issue.disabled_core_fields.include?('assigned_to_id')
43
  unless @issue.disabled_core_fields.include?('assigned_to_id') || @issue.hidden_attribute?('assigned_to_id')
40 44
    rows.left l(:field_assigned_to), avatar(@issue.assigned_to, :size => "14").to_s.html_safe + (@issue.assigned_to ? link_to_user(@issue.assigned_to) : "-"), :class => 'assigned-to'
41 45
  end
42
  unless @issue.disabled_core_fields.include?('category_id')
46
  unless @issue.disabled_core_fields.include?('category_id') || @issue.hidden_attribute?('category_id')
43 47
    rows.left l(:field_category), h(@issue.category ? @issue.category.name : "-"), :class => 'category'
44 48
  end
45
  unless @issue.disabled_core_fields.include?('fixed_version_id')
49
  unless @issue.disabled_core_fields.include?('fixed_version_id') || @issue.hidden_attribute?('fixed_version_id')
46 50
    rows.left l(:field_fixed_version), (@issue.fixed_version ? link_to_version(@issue.fixed_version) : "-"), :class => 'fixed-version'
47 51
  end
48 52

  
49
  unless @issue.disabled_core_fields.include?('start_date')
53
  unless @issue.disabled_core_fields.include?('start_date') || @issue.hidden_attribute?('start_date')
50 54
    rows.right l(:field_start_date), format_date(@issue.start_date), :class => 'start-date'
51 55
  end
52
  unless @issue.disabled_core_fields.include?('due_date')
56
  unless @issue.disabled_core_fields.include?('due_date') || @issue.hidden_attribute?('due_date')
53 57
    rows.right l(:field_due_date), format_date(@issue.due_date), :class => 'due-date'
54 58
  end
55
  unless @issue.disabled_core_fields.include?('done_ratio')
59
  unless @issue.disabled_core_fields.include?('done_ratio') || @issue.hidden_attribute?('done_ratio')
56 60
    rows.right l(:field_done_ratio), progress_bar(@issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%"), :class => 'progress'
57 61
  end
58
  unless @issue.disabled_core_fields.include?('estimated_hours')
62
  unless @issue.disabled_core_fields.include?('estimated_hours') || @issue.hidden_attribute?('estimated_hours')
59 63
    unless @issue.estimated_hours.nil?
60 64
      rows.right l(:field_estimated_hours), l_hours(@issue.estimated_hours), :class => 'estimated-hours'
61 65
    end
config/locales/en.yml (working copy)
879 879
  label_fields_permissions: Fields permissions
880 880
  label_readonly: Read-only
881 881
  label_required: Required
882
  label_hidden: " Hidden "
882 883
  label_attribute_of_project: "Project's %{name}"
883 884
  label_attribute_of_author: "Author's %{name}"
884 885
  label_attribute_of_assigned_to: "Assignee's %{name}"
lib/redmine/export/pdf.rb (working copy)
520 520
        pdf.Ln
521 521

  
522 522
        left = []
523
        left << [l(:field_status), issue.status]
524
        left << [l(:field_priority), issue.priority]
525
        left << [l(:field_assigned_to), issue.assigned_to] unless issue.disabled_core_fields.include?('assigned_to_id')
526
        left << [l(:field_category), issue.category] unless issue.disabled_core_fields.include?('category_id')
527
        left << [l(:field_fixed_version), issue.fixed_version] unless issue.disabled_core_fields.include?('fixed_version_id')
523
        left << [l(:field_status), issue.status] unless issue.hidden_attribute?('status')
524
        left << [l(:field_priority), issue.priority] unless issue.hidden_attribute?('priority')
525
        left << [l(:field_assigned_to), issue.assigned_to] unless issue.disabled_core_fields.include?('assigned_to_id') or issue.hidden_attribute?('assigned_to_id')
526
        left << [l(:field_category), issue.category] unless issue.disabled_core_fields.include?('category_id') or issue.hidden_attribute?('category_id')
527
        left << [l(:field_fixed_version), issue.fixed_version] unless issue.disabled_core_fields.include?('fixed_version_id') or issue.hidden_attribute?('fixed_version_id')
528 528

  
529 529
        right = []
530
        right << [l(:field_start_date), format_date(issue.start_date)] unless issue.disabled_core_fields.include?('start_date')
531
        right << [l(:field_due_date), format_date(issue.due_date)] unless issue.disabled_core_fields.include?('due_date')
532
        right << [l(:field_done_ratio), "#{issue.done_ratio}%"] unless issue.disabled_core_fields.include?('done_ratio')
533
        right << [l(:field_estimated_hours), l_hours(issue.estimated_hours)] unless issue.disabled_core_fields.include?('estimated_hours')
530
        right << [l(:field_start_date), format_date(issue.start_date)] unless issue.disabled_core_fields.include?('start_date') or issue.hidden_attribute?('start_date')
531
        right << [l(:field_due_date), format_date(issue.due_date)] unless issue.disabled_core_fields.include?('due_date') or issue.hidden_attribute?('due_date')
532
        right << [l(:field_done_ratio), "#{issue.done_ratio}%"] unless issue.disabled_core_fields.include?('done_ratio') or issue.hidden_attribute?('done_ratio')
533
        right << [l(:field_estimated_hours), l_hours(issue.estimated_hours)] unless issue.disabled_core_fields.include?('estimated_hours') or issue.hidden_attribute?('estimated_hours')
534 534
        right << [l(:label_spent_time), l_hours(issue.total_spent_hours)] if User.current.allowed_to?(:view_time_entries, issue.project)
535 535

  
536 536
        rows = left.size > right.size ? left.size : right.size
......
541 541
          right << nil
542 542
        end
543 543

  
544
        half = (issue.custom_field_values.size / 2.0).ceil
545
        issue.custom_field_values.each_with_index do |custom_value, i|
546
          (i < half ? left : right) << [custom_value.custom_field.name, show_value(custom_value)]
544
        half = (issue.viewable_custom_field_values.size / 2.0).ceil
545
        issue.viewable_custom_field_values.each_with_index do |custom_value, i|
546
          (i < half ? left : right) << [custom_value.custom_field.name, show_value(custom_value)] unless issue.hidden_attribute?(custom_value.custom_field.name)
547 547
        end
548 548

  
549 549
        rows = left.size > right.size ? left.size : right.size
(3-3/13)