diff --git a/CHANGELOG b/CHANGELOG index d3119846760b1ae6709fe79633c68a072458684d..842978468ad335e7461312a7a53857c97a7226d2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +v 6.5.0 + - Dropdown menus on issue#show page for assignee and milestone (Jason Blanchard) + v 6.4.0 - Added sorting to project issues page (Jason Blanchard) - Assembla integration (Carlos Paramio) diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee index c273ddbd39147b0ab9aaf916d91fce01428b9303..43571409bc51836902c310e9c3e98d43185f9b0c 100644 --- a/app/assets/javascripts/issues.js.coffee +++ b/app/assets/javascripts/issues.js.coffee @@ -79,3 +79,9 @@ $("#update_issues_ids").val [] $(".issues_bulk_update").hide() $(".issues-filters").show() + +$ -> + $('.edit-issue.inline-update input[type="submit"]').hide(); + $("body").on "change", ".edit-issue.inline-update select", -> + $(this).submit() + diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss index 792bcef02f2dcd98168e98684d5bb69cf3d8a4b7..68e8f3fa08aa6ff623d774628ead460cd0a619b0 100644 --- a/app/assets/stylesheets/sections/issues.scss +++ b/app/assets/stylesheets/sections/issues.scss @@ -119,3 +119,8 @@ input.check_all_issues { background-color: #f4f4f4; } } + +.edit-issue.inline-update select { + width: 100%; + max-width: 230px; +} diff --git a/app/views/projects/issues/_issue_context.html.haml b/app/views/projects/issues/_issue_context.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..29eb338d44dbf35157b4739a10ee136a7c876e1b --- /dev/null +++ b/app/views/projects/issues/_issue_context.html.haml @@ -0,0 +1,31 @@ += form_for [@project, @issue], :remote => true, :html => {:class => 'edit-issue inline-update'} do |f| + .pull-right + Created by #{link_to_member(@project, issue.author)} + - if issue.assignee + \ and currently assigned to + + - if can?(current_user, :modify_issue, @issue) + = link_to profile_path(issue.assignee) do + = image_tag(avatar_icon(issue.assignee.email), :class => 'avatar avatar-inline s16 assignee') if issue.assignee + = f.select(:assignee_id, @project.team.members.sort_by(&:name).map {|p| [ p.name, p.id ] }, { include_blank: "Assign to user (none):" }, {class: 'chosen'}) + - elsif issue.assignee + = link_to_member(@project, @issue.assignee) + + - if issue.milestone + - milestone = issue.milestone + %cite.cgray and attached to milestone + + - if can?(current_user, :modify_issue, @issue) + = f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone (none):" }, {class: 'chosen'}) + + = hidden_field_tag :issue_context + = f.submit :class => 'btn' + - elsif issue.milestone + = link_to issue.milestone.title, project_milestone_path + +.pull-right + - issue.labels.each do |label| + %span{class: "label #{label_css_class(label.name)}"} + %i.icon-tag + = label.name + diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 36ea57805a8b0b23477bc752d9b3fd5d569545f3..b23e577c6f9ae40fecc750f0c2c2101c4a08023c 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -26,7 +26,12 @@ .back-link = link_to project_issues_path(@project) do ← To issues list - + %span.milestone-nav-link + - if @issue.milestone + | + = link_to project_milestone_path(@project, @issue.milestone) do + <strong>Milestone:</strong> + = @issue.milestone.title .ui-box.ui-box-show .ui-box-head @@ -39,21 +44,7 @@ .ui-box-body %cite.cgray - Created by #{link_to_member(@project, @issue.author)} - - if @issue.assignee - \ and currently assigned to #{link_to_member(@project, @issue.assignee)} - - - if @issue.milestone - - milestone = @issue.milestone - %cite.cgray and attached to milestone - %strong= link_to_gfm truncate(milestone.title, length: 20), project_milestone_path(milestone.project, milestone) - - .pull-right - - @issue.labels.each do |label| - %span{class: "label #{label_css_class(label.name)}"} - %i.icon-tag - = label.name - + = render partial: 'issue_context', locals: { issue: @issue } - if @issue.description.present? .ui-box-bottom @@ -73,4 +64,4 @@ - @issue.participants.each do |participant| = link_to_member(@project, participant, name: false, size: 24) -.voting_notes#notes= render "projects/notes/notes_with_form" \ No newline at end of file +.voting_notes#notes= render "projects/notes/notes_with_form" diff --git a/app/views/projects/issues/update.js.haml b/app/views/projects/issues/update.js.haml index 7f66022a2de34d851856dd0ba4ad9e1ff5f9f549..eb27faa3126c55832dfc5025b030ffa0dee08258 100644 --- a/app/views/projects/issues/update.js.haml +++ b/app/views/projects/issues/update.js.haml @@ -2,3 +2,12 @@ - if @issue.valid? :plain $("##{dom_id(@issue)}").fadeOut(); +- elsif params[:issue_context] + $('.ui-box-body').html("#{escape_javascript(render partial: 'issue_context', locals: { issue: @issue })}"); + $('.ui-box-body').effect('highlight'); + $('.chosen').chosen(); + $('.edit-issue.inline-update input[type="submit"]').hide(); + - if @issue.milestone + $('.milestone-nav-link').replaceWith("#{escape_javascript(link_to "| #{@issue.milestone.title}", project_milestone_path(@issue.project, @issue.milestone), :class => 'milestone-nav-link')}") + - else + $('.milestone-nav-link').html('') diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index bb0c4dbd5ddede120fe22080fecce62966b3b651..e33684ed8324bbdffeaf496c1a5a9bad41291b4b 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -175,6 +175,84 @@ describe "Issues" do end end + describe 'update assignee from issue#show' do + let(:issue) { create(:issue, project: project, author: @user) } + + context 'by autorized user' do + + it 'with dropdown menu' do + visit project_issue_path(project, issue) + + find('.edit-issue.inline-update').select(project.team.members.first.name, from: 'issue_assignee_id') + click_button 'Update Issue' + + page.should have_content "currently assigned to" + page.has_select?('issue_assignee_id', :selected => project.team.members.first.name) + end + end + + context 'by unauthorized user' do + + let(:guest) { create(:user) } + + before :each do + project.team << [[guest], :guest] + issue.assignee = @user + issue.save + end + + it 'shows assignee text' do + logout + login_with guest + + visit project_issue_path(project, issue) + page.should have_content "currently assigned to #{issue.assignee.name}" + + end + end + + end + + describe 'update milestone from issue#show' do + let!(:issue) { create(:issue, project: project, author: @user) } + let!(:milestone) { create(:milestone, project: project) } + + context 'by authorized user' do + + it 'with dropdown menu' do + visit project_issue_path(project, issue) + + p find('.edit-issue.inline-update').text + + find('.edit-issue.inline-update').select(milestone.title, from: 'issue_milestone_id') + click_button 'Update Issue' + + page.should have_content "and attached to milestone" + page.has_select?('issue_assignee_id', :selected => milestone.title) + end + end + + context 'by unauthorized user' do + + let(:guest) { create(:user) } + + before :each do + project.team << [[guest], :guest] + issue.milestone = milestone + issue.save + end + + it 'shows milestone text' do + logout + login_with guest + + visit project_issue_path(project, issue) + + page.should have_content "attached to milestone #{milestone.title}" + end + end + end + def first_issue all("ul.issues-list li").first.text end