diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index 6bb2bc217..c2500f50b 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -73,10 +73,20 @@ class IssueQuery < Query options[:draw_progress_line] = (arg == '1' ? '1' : nil) end + def draw_assigned_to_names + r = options[:draw_assigned_to_names] + r == '1' + end + + def draw_assigned_to_names=(arg) + options[:draw_assigned_to_names] = (arg == '1' ? '1' : nil) + end + def build_from_params(params, defaults={}) super self.draw_relations = params[:draw_relations] || (params[:query] && params[:query][:draw_relations]) self.draw_progress_line = params[:draw_progress_line] || (params[:query] && params[:query][:draw_progress_line]) + self.draw_assigned_to_names = params[:draw_assigned_to_names] || (params[:query] && params[:query][:draw_assigned_to_names]) self end diff --git a/app/views/gantts/show.html.erb b/app/views/gantts/show.html.erb index 9703e962e..2b58552dc 100644 --- a/app/views/gantts/show.html.erb +++ b/app/views/gantts/show.html.erb @@ -53,6 +53,15 @@ + +
+ <%= l(:field_assigned_to) %> + +
+ @@ -92,6 +101,7 @@ subject_width = 330 header_height = 18 + assigned_to_width = 100 headers_height = header_height show_weeks = false @@ -125,7 +135,7 @@

<%= l(:notice_gantt_chart_truncated, :max => @gantt.max_rows) %>

<% end %> - +
- +
<% @@ -155,7 +165,34 @@ <% end %> <% end %>
<% @@ -370,8 +407,7 @@ $(function() { drawGanttHandler(); resizableSubjectColumn(); - $("#draw_relations").change(drawGanttHandler); - $("#draw_progress_line").change(drawGanttHandler); + $("#draw_relations, #draw_progress_line, #draw_assigned_to_names").change(drawGanttHandler); }); $(window).resize(function() { drawGanttHandler(); diff --git a/app/views/queries/_form.html.erb b/app/views/queries/_form.html.erb index f424e103c..c267e098c 100644 --- a/app/views/queries/_form.html.erb +++ b/app/views/queries/_form.html.erb @@ -42,6 +42,7 @@

+

<% end %> diff --git a/lib/redmine/helpers/gantt.rb b/lib/redmine/helpers/gantt.rb index 4ff2ec944..bf0e73842 100644 --- a/lib/redmine/helpers/gantt.rb +++ b/lib/redmine/helpers/gantt.rb @@ -76,6 +76,7 @@ module Redmine @date_to = (@date_from >> @months) - 1 @subjects = '' @lines = '' + @assigned_to_names = '' @number_of_rows = nil @truncated = false if options.has_key?(:max_rows) @@ -135,6 +136,12 @@ module Redmine @lines end + # Renders the assigned_to_names of the Gantt chart, the right side of subjects. + def assigned_to_names(options={}) + render(options.merge(:only => :assigned_to_names)) unless @assigned_to_names_rendered + @assigned_to_names + end + # Returns issues that will be rendered def issues @issues ||= @query.issues( @@ -196,8 +203,9 @@ module Redmine :indent_increment => 20, :render => :subject, :format => :html}.merge(options) indent = options[:indent] || 4 - @subjects = '' unless options[:only] == :lines - @lines = '' unless options[:only] == :subjects + @subjects = '' unless options[:only] == :lines || options[:only] == :assigned_to_names + @lines = '' unless options[:only] == :subjects || options[:only] == :assigned_to_names + @assigned_to_names = '' unless options[:only] == :lines || options[:only] == :subjects @number_of_rows = 0 begin Project.project_tree(projects) do |project, level| @@ -207,8 +215,9 @@ module Redmine rescue MaxLinesLimitReached @truncated = true end - @subjects_rendered = true unless options[:only] == :lines - @lines_rendered = true unless options[:only] == :subjects + @subjects_rendered = true unless options[:only] == :lines || options[:only] == :assigned_to_names + @lines_rendered = true unless options[:only] == :subjects || options[:only] == :assigned_to_names + @assigned_to_names_rendered = true unless options[:only] == :lines || options[:only] == :subjects render_end(options) end @@ -254,8 +263,9 @@ module Redmine def render_object_row(object, options) class_name = object.class.name.downcase - send("subject_for_#{class_name}", object, options) unless options[:only] == :lines - send("line_for_#{class_name}", object, options) unless options[:only] == :subjects + send("subject_for_#{class_name}", object, options) unless options[:only] == :lines || options[:only] == :assigned_to_names + send("line_for_#{class_name}", object, options) unless options[:only] == :subjects || options[:only] == :assigned_to_names + assigned_to_name(object, options) unless options[:only] == :lines || options[:only] == :subjects options[:top] += options[:top_increment] @number_of_rows += 1 if @max_rows && @number_of_rows >= @max_rows @@ -323,6 +333,18 @@ module Redmine end end + def assigned_to_name(issue, options) + if issue.is_a?(Issue) && options[:format] == :html && issue.assigned_to.present? + style = "position: absolute;top: #{options[:top]}px;" + content = view.avatar(issue.assigned_to, + :class => 'gravatar icon-gravatar', + :size => 10) + view.link_to_user(issue.assigned_to) + assigned_to_name = view.content_tag(:div, content.html_safe, :style => style, :class => 'issue-assigned-name') + @assigned_to_names << assigned_to_name + assigned_to_name + end + end + def subject(label, options, object=nil) send "#{options[:format]}_subject", options, label, object end diff --git a/public/javascripts/gantt.js b/public/javascripts/gantt.js index 2e71178b0..7346b6319 100644 --- a/public/javascripts/gantt.js +++ b/public/javascripts/gantt.js @@ -161,6 +161,36 @@ function drawGanttProgressLines() { } } +function drawAssignedToNames(){ + if ($("#draw_assigned_to_names").prop('checked')){ + $('td.gantt_assigned_to_names_column').show(); + $('td.gantt_assigned_to_names_column').resizable({ + alsoResize: ".gantt_assigned_to_names_container, .gantt_assigned_to_names_container>.gantt_hdr, .issue-assigned-name", + minWidth: 20, + handles: "e", + containment: "#content", + create: function( event, ui ) { + $(".ui-resizable-e").css("cursor","ew-resize"); + } + }).on('resize', function (e) { + e.stopPropagation(); + }); + if(isMobile()) { + var width = Math.round($('.gantt_container').width()*0.15) + $('.gantt_assigned_to_names_container>.gantt_hdr').width(width-2); + $('.gantt_assigned_to_names_container, .gantt_assigned_to_names_column').width(width); + $('.issue-assigned-name').each(function(){ + $(this).width($(".gantt_assigned_to_names_column").width()); + }); + $('td.gantt_assigned_to_names_column').resizable('disable'); + }else{ + $('td.gantt_assigned_to_names_column').resizable('enable'); + }; + }else{ + $('td.gantt_assigned_to_names_column').hide(); + } +} + function drawGanttHandler() { var folder = document.getElementById('gantt_draw_area'); if(draw_gantt != null) @@ -168,6 +198,7 @@ function drawGanttHandler() { else draw_gantt = Raphael(folder); setDrawArea(); + drawAssignedToNames(); if ($("#draw_progress_line").prop('checked')) drawGanttProgressLines(); if ($("#draw_relations").prop('checked')) diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index 7d2b662e1..51d70913a 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -1162,8 +1162,9 @@ div.wiki img {vertical-align:middle; max-width:100%;} .gantt_hdr.nwday {background-color:#f1f1f1; color:#999;} -.gantt_subjects { font-size: 0.8em; } -.gantt_subjects div { line-height:16px;height:16px;overflow:hidden;white-space:nowrap;text-overflow: ellipsis; } +.gantt_subjects, .issue-assigned-name { font-size: 0.8em; } +.gantt_subjects div, .issue-assigned-name { line-height:16px;height:16px;overflow:hidden;white-space:nowrap;text-overflow: ellipsis; } +.issue-assigned-name { padding: 0px 3px; width: 100px; } .task { position: absolute; diff --git a/public/stylesheets/responsive.css b/public/stylesheets/responsive.css index 118039d7e..58abc0f54 100644 --- a/public/stylesheets/responsive.css +++ b/public/stylesheets/responsive.css @@ -693,7 +693,7 @@ * [4] maintain width due to [3] */ .gantt_subjects_column { - width: 60% !important; /* [1] */ + width: 50% !important; /* [1] */ } .gantt_subjects_container { @@ -843,4 +843,3 @@ #login-form {width:100%; margin-top:2em;} } - diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb index 5149a447d..9bc02c646 100644 --- a/test/functional/queries_controller_test.rb +++ b/test/functional/queries_controller_test.rb @@ -283,7 +283,8 @@ class QueriesControllerTest < Redmine::ControllerTest :query => { :name => "test_create_from_gantt", :draw_relations => '1', - :draw_progress_line => '1' + :draw_progress_line => '1', + :draw_assigned_to_names => '1' } } assert_response 302 @@ -292,6 +293,7 @@ class QueriesControllerTest < Redmine::ControllerTest assert_redirected_to "/issues/gantt?query_id=#{query.id}" assert_equal true, query.draw_relations assert_equal true, query.draw_progress_line + assert_equal true, query.draw_assigned_to_names end def test_create_project_query_from_gantt @@ -309,7 +311,8 @@ class QueriesControllerTest < Redmine::ControllerTest :query => { :name => "test_create_from_gantt", :draw_relations => '0', - :draw_progress_line => '0' + :draw_progress_line => '0', + :draw_assigned_to_names => '0' } } assert_response 302 @@ -318,6 +321,7 @@ class QueriesControllerTest < Redmine::ControllerTest assert_redirected_to "/projects/ecookbook/issues/gantt?query_id=#{query.id}" assert_equal false, query.draw_relations assert_equal false, query.draw_progress_line + assert_equal false, query.draw_assigned_to_names end def test_create_project_public_query_should_force_private_without_manage_public_queries_permission diff --git a/test/unit/lib/redmine/helpers/gantt_test.rb b/test/unit/lib/redmine/helpers/gantt_test.rb index d7dc956ce..b9c72b152 100644 --- a/test/unit/lib/redmine/helpers/gantt_test.rb +++ b/test/unit/lib/redmine/helpers/gantt_test.rb @@ -237,6 +237,16 @@ class Redmine::Helpers::GanttHelperTest < Redmine::HelperTest assert_select "div.tooltip", /#{@issue.subject}/ end + test "#assigned_to_names" do + create_gantt + issue = Issue.generate! + issue.update(:assigned_to_id => issue.assignable_users.first.id) + @project.issues << issue + @output_buffer = @gantt.assigned_to_names(:format => :html) + + assert_select "div.issue-assigned-name span", /#{issue.assigned_to.name}/ + end + test "#subject_for_project" do create_gantt @output_buffer = @gantt.subject_for_project(@project, :format => :html) @@ -418,6 +428,18 @@ class Redmine::Helpers::GanttHelperTest < Redmine::HelperTest assert_select "div.label", :text => 'line' end + test "#assigned_to_name" do + create_gantt + options = {:top => 64, :format => :html} + issue = Issue.generate! + issue.assigned_to_id = issue.assignable_users.first.id + @output_buffer = @gantt.assigned_to_name(issue, options) + + assert_select 'div.issue-assigned-name[style*="position: absolute;top: 64px;"]' do + assert_select 'span', issue.assigned_to.name + end + end + def test_sort_issues_no_date project = Project.generate! issue1 = Issue.generate!(:subject => "test", :project => project)