summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorGo MAEDA <maeda@farend.jp>2019-08-09 09:31:16 +0000
committerGo MAEDA <maeda@farend.jp>2019-08-09 09:31:16 +0000
commit3c91a3d5b2f9a2ce55b941ee68fbaa596b5b3052 (patch)
treed54cf120aea24f14b4eb7a06f41749f1eacd6e7a /app
parent433d8a081f29785ac2d21cba36592678f4001511 (diff)
downloadredmine-3c91a3d5b2f9a2ce55b941ee68fbaa596b5b3052.tar.gz
redmine-3c91a3d5b2f9a2ce55b941ee68fbaa596b5b3052.zip
Per role visibility settings for spent time custom fields (#31859).
Patch by Marius BALTEANU. git-svn-id: http://svn.redmine.org/redmine/trunk@18358 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r--app/models/issue_query.rb6
-rw-r--r--app/models/time_entry.rb7
-rw-r--r--app/models/time_entry_custom_field.rb10
-rw-r--r--app/views/custom_fields/_form.html.erb106
-rw-r--r--app/views/custom_fields/_visibility_by_role_selector.html.erb20
-rw-r--r--app/views/timelog/_form.html.erb2
-rw-r--r--app/views/timelog/index.api.rsb2
7 files changed, 91 insertions, 62 deletions
diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb
index 5245d5ba0..7701cbfe2 100644
--- a/app/models/issue_query.rb
+++ b/app/models/issue_query.rb
@@ -40,8 +40,10 @@ class IssueQuery < Query
QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date", :groupable => true),
QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours", :totalable => true),
QueryColumn.new(:total_estimated_hours,
- :sortable => -> { "COALESCE((SELECT SUM(estimated_hours) FROM #{Issue.table_name} subtasks" +
- " WHERE #{Issue.visible_condition(User.current).gsub(/\bissues\b/, 'subtasks')} AND subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)" },
+ :sortable => -> {
+ "COALESCE((SELECT SUM(estimated_hours) FROM #{Issue.table_name} subtasks" +
+ " WHERE #{Issue.visible_condition(User.current).gsub(/\bissues\b/, 'subtasks')} AND subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)"
+ },
:default_order => 'desc'),
QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true),
TimestampQueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc', :groupable => true),
diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb
index 9701622c8..d2661d078 100644
--- a/app/models/time_entry.rb
+++ b/app/models/time_entry.rb
@@ -189,6 +189,13 @@ class TimeEntry < ActiveRecord::Base
editable_custom_field_values(user).map(&:custom_field).uniq
end
+ def visible_custom_field_values(user = nil)
+ user ||= User.current
+ custom_field_values.select do |value|
+ value.custom_field.visible_by?(project, user)
+ end
+ end
+
def assignable_users
users = []
if project
diff --git a/app/models/time_entry_custom_field.rb b/app/models/time_entry_custom_field.rb
index 9ef820efb..601e1b962 100644
--- a/app/models/time_entry_custom_field.rb
+++ b/app/models/time_entry_custom_field.rb
@@ -21,5 +21,13 @@ class TimeEntryCustomField < CustomField
def type_name
:label_spent_time
end
-end
+ def visible_by?(project, user=User.current)
+ super || (roles & user.roles_for_project(project)).present?
+ end
+
+ def validate_custom_field
+ super
+ errors.add(:base, l(:label_role_plural) + ' ' + l('activerecord.errors.messages.blank')) unless visible? || roles.present?
+ end
+end
diff --git a/app/views/custom_fields/_form.html.erb b/app/views/custom_fields/_form.html.erb
index cac457ce2..e428a27c6 100644
--- a/app/views/custom_fields/_form.html.erb
+++ b/app/views/custom_fields/_form.html.erb
@@ -31,83 +31,75 @@
</div>
<div class="splitcontentright">
-<div class="box tabular">
<% case @custom_field.class.name
when "IssueCustomField" %>
- <p><%= f.check_box :is_required %></p>
- <% if @custom_field.format.is_filter_supported %>
- <p><%= f.check_box :is_filter %></p>
- <% end %>
- <% if @custom_field.format.searchable_supported %>
- <p><%= f.check_box :searchable %></p>
- <% end %>
+ <div class="box tabular">
+ <p><%= f.check_box :is_required %></p>
+ <% if @custom_field.format.is_filter_supported %>
+ <p><%= f.check_box :is_filter %></p>
+ <% end %>
+ <% if @custom_field.format.searchable_supported %>
+ <p><%= f.check_box :searchable %></p>
+ <% end %>
+ </div>
+ <%= render :partial => 'visibility_by_role_selector' %>
<% when "UserCustomField" %>
- <p><%= f.check_box :is_required %></p>
- <p><%= f.check_box :visible %></p>
- <p><%= f.check_box :editable %></p>
- <% if @custom_field.format.is_filter_supported %>
- <p><%= f.check_box :is_filter %></p>
- <% end %>
+ <div class="box tabular">
+ <p><%= f.check_box :is_required %></p>
+ <p><%= f.check_box :visible %></p>
+ <p><%= f.check_box :editable %></p>
+ <% if @custom_field.format.is_filter_supported %>
+ <p><%= f.check_box :is_filter %></p>
+ <% end %>
+ </div>
<% when "ProjectCustomField" %>
- <p><%= f.check_box :is_required %></p>
- <p><%= f.check_box :visible %></p>
- <% if @custom_field.format.searchable_supported %>
- <p><%= f.check_box :searchable %></p>
- <% end %>
- <% if @custom_field.format.is_filter_supported %>
- <p><%= f.check_box :is_filter %></p>
- <% end %>
+ <div class="box tabular">
+ <p><%= f.check_box :is_required %></p>
+ <p><%= f.check_box :visible %></p>
+ <% if @custom_field.format.searchable_supported %>
+ <p><%= f.check_box :searchable %></p>
+ <% end %>
+ <% if @custom_field.format.is_filter_supported %>
+ <p><%= f.check_box :is_filter %></p>
+ <% end %>
+ </div>
<% when "VersionCustomField" %>
- <p><%= f.check_box :is_required %></p>
- <% if @custom_field.format.is_filter_supported %>
- <p><%= f.check_box :is_filter %></p>
- <% end %>
+ <div class="box tabular">
+ <p><%= f.check_box :is_required %></p>
+ <% if @custom_field.format.is_filter_supported %>
+ <p><%= f.check_box :is_filter %></p>
+ <% end %>
+ </div>
<% when "GroupCustomField" %>
- <p><%= f.check_box :is_required %></p>
- <% if @custom_field.format.is_filter_supported %>
- <p><%= f.check_box :is_filter %></p>
- <% end %>
+ <div class="box tabular">
+ <p><%= f.check_box :is_required %></p>
+ <% if @custom_field.format.is_filter_supported %>
+ <p><%= f.check_box :is_filter %></p>
+ <% end %>
+ </div>
<% when "TimeEntryCustomField" %>
- <p><%= f.check_box :is_required %></p>
- <% if @custom_field.format.is_filter_supported %>
- <p><%= f.check_box :is_filter %></p>
- <% end %>
+ <div class="box tabular">
+ <p><%= f.check_box :is_required %></p>
+ <% if @custom_field.format.is_filter_supported %>
+ <p><%= f.check_box :is_filter %></p>
+ <% end %>
+ </div>
+ <%= render :partial => 'visibility_by_role_selector' %>
<% else %>
+ <div class="box tabular">
<p><%= f.check_box :is_required %></p>
-
+ </div>
<% end %>
<%= call_hook(:"view_custom_fields_form_#{@custom_field.type.to_s.underscore}", :custom_field => @custom_field, :form => f) %>
-</div>
<% if @custom_field.is_a?(IssueCustomField) %>
- <fieldset class="box tabular"><legend><%= l(:field_visible) %></legend>
- <label class="block">
- <%= radio_button_tag 'custom_field[visible]', 1, @custom_field.visible?, :id => 'custom_field_visible_on',
- :data => {:disables => '.custom_field_role input'} %>
- <%= l(:label_visibility_public) %>
- </label>
- <label class="block">
- <%= radio_button_tag 'custom_field[visible]', 0, !@custom_field.visible?, :id => 'custom_field_visible_off',
- :data => {:enables => '.custom_field_role input'} %>
- <%= l(:label_visibility_roles) %>:
- </label>
- <% role_ids = @custom_field.role_ids %>
- <% Role.givable.sorted.each do |role| %>
- <label class="block custom_field_role" style="padding-left:2em;">
- <%= check_box_tag 'custom_field[role_ids][]', role.id, role_ids.include?(role.id), :id => nil %>
- <%= role.name %>
- </label>
- <% end %>
- <%= hidden_field_tag 'custom_field[role_ids][]', '' %>
- </fieldset>
-
<fieldset class="box" id="custom_field_tracker_ids"><legend><%= toggle_checkboxes_link("#custom_field_tracker_ids input[type=checkbox]") %><%=l(:label_tracker_plural)%></legend>
<% tracker_ids = @custom_field.tracker_ids %>
<% Tracker.sorted.each do |tracker| %>
diff --git a/app/views/custom_fields/_visibility_by_role_selector.html.erb b/app/views/custom_fields/_visibility_by_role_selector.html.erb
new file mode 100644
index 000000000..552bc7906
--- /dev/null
+++ b/app/views/custom_fields/_visibility_by_role_selector.html.erb
@@ -0,0 +1,20 @@
+<fieldset class="box tabular"><legend><%= l(:field_visible) %></legend>
+ <label class="block">
+ <%= radio_button_tag 'custom_field[visible]', 1, @custom_field.visible?, :id => 'custom_field_visible_on',
+ :data => {:disables => '.custom_field_role input'} %>
+ <%= l(:label_visibility_public) %>
+ </label>
+ <label class="block">
+ <%= radio_button_tag 'custom_field[visible]', 0, !@custom_field.visible?, :id => 'custom_field_visible_off',
+ :data => {:enables => '.custom_field_role input'} %>
+ <%= l(:label_visibility_roles) %>:
+ </label>
+ <% role_ids = @custom_field.role_ids %>
+ <% Role.givable.sorted.each do |role| %>
+ <label class="block custom_field_role" style="padding-left:2em;">
+ <%= check_box_tag 'custom_field[role_ids][]', role.id, role_ids.include?(role.id), :id => nil %>
+ <%= role.name %>
+ </label>
+ <% end %>
+ <%= hidden_field_tag 'custom_field[role_ids][]', '' %>
+</fieldset>
diff --git a/app/views/timelog/_form.html.erb b/app/views/timelog/_form.html.erb
index 691da9ed1..bfeb67337 100644
--- a/app/views/timelog/_form.html.erb
+++ b/app/views/timelog/_form.html.erb
@@ -23,7 +23,7 @@
<p><%= f.hours_field :hours, :size => 6, :required => true %></p>
<p><%= f.text_field :comments, :size => 100, :maxlength => 1024, :required => Setting.timelog_required_fields.include?('comments') %></p>
<p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
- <% @time_entry.custom_field_values.each do |value| %>
+ <% @time_entry.editable_custom_field_values.each do |value| %>
<p><%= custom_field_tag_with_label :time_entry, value %></p>
<% end %>
<%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %>
diff --git a/app/views/timelog/index.api.rsb b/app/views/timelog/index.api.rsb
index d281e89b2..976714869 100644
--- a/app/views/timelog/index.api.rsb
+++ b/app/views/timelog/index.api.rsb
@@ -12,7 +12,7 @@ api.array :time_entries, api_meta(:total_count => @entry_count, :offset => @offs
api.created_on time_entry.created_on
api.updated_on time_entry.updated_on
- render_api_custom_values time_entry.custom_field_values, api
+ render_api_custom_values time_entry.visible_custom_field_values, api
end
end
end