Commit 5405f19baced5972472d5d8bdd6a8c77d59e68ea

Authored by Dmitriy Zaporozhets
2 parents 8bcb2ff2 65448e2f

Merge branch 'feature-issue-actions' of https://github.com/jasonblanchard/gitlabhq into 6-5-dev

  1 +v 6.5.0
  2 + - Dropdown menus on issue#show page for assignee and milestone (Jason Blanchard)
  3 +
1 v 6.4.0 4 v 6.4.0
2 - Added sorting to project issues page (Jason Blanchard) 5 - Added sorting to project issues page (Jason Blanchard)
3 - Assembla integration (Carlos Paramio) 6 - Assembla integration (Carlos Paramio)
app/assets/javascripts/issues.js.coffee
@@ -79,3 +79,9 @@ @@ -79,3 +79,9 @@
79 $("#update_issues_ids").val [] 79 $("#update_issues_ids").val []
80 $(".issues_bulk_update").hide() 80 $(".issues_bulk_update").hide()
81 $(".issues-filters").show() 81 $(".issues-filters").show()
  82 +
  83 +$ ->
  84 + $('.edit-issue.inline-update input[type="submit"]').hide();
  85 + $("body").on "change", ".edit-issue.inline-update select", ->
  86 + $(this).submit()
  87 +
app/assets/stylesheets/sections/issues.scss
@@ -119,3 +119,8 @@ input.check_all_issues { @@ -119,3 +119,8 @@ input.check_all_issues {
119 background-color: #f4f4f4; 119 background-color: #f4f4f4;
120 } 120 }
121 } 121 }
  122 +
  123 +.edit-issue.inline-update select {
  124 + width: 100%;
  125 + max-width: 230px;
  126 +}
app/views/projects/issues/_issue_context.html.haml 0 → 100644
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
  1 += form_for [@project, @issue], :remote => true, :html => {:class => 'edit-issue inline-update'} do |f|
  2 + .pull-right
  3 + Created by #{link_to_member(@project, issue.author)}
  4 + - if issue.assignee
  5 + \ and currently assigned to
  6 +
  7 + - if can?(current_user, :modify_issue, @issue)
  8 + = link_to profile_path(issue.assignee) do
  9 + = image_tag(avatar_icon(issue.assignee.email), :class => 'avatar avatar-inline s16 assignee') if issue.assignee
  10 + = f.select(:assignee_id, @project.team.members.sort_by(&:name).map {|p| [ p.name, p.id ] }, { include_blank: "Assign to user (none):" }, {class: 'chosen'})
  11 + - elsif issue.assignee
  12 + = link_to_member(@project, @issue.assignee)
  13 +
  14 + - if issue.milestone
  15 + - milestone = issue.milestone
  16 + %cite.cgray and attached to milestone
  17 +
  18 + - if can?(current_user, :modify_issue, @issue)
  19 + = f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone (none):" }, {class: 'chosen'})
  20 +
  21 + = hidden_field_tag :issue_context
  22 + = f.submit :class => 'btn'
  23 + - elsif issue.milestone
  24 + = link_to issue.milestone.title, project_milestone_path
  25 +
  26 +.pull-right
  27 + - issue.labels.each do |label|
  28 + %span{class: "label #{label_css_class(label.name)}"}
  29 + %i.icon-tag
  30 + = label.name
  31 +  
app/views/projects/issues/show.html.haml
@@ -26,7 +26,12 @@ @@ -26,7 +26,12 @@
26 .back-link 26 .back-link
27 = link_to project_issues_path(@project) do 27 = link_to project_issues_path(@project) do
28 ← To issues list 28 ← To issues list
29 - 29 + %span.milestone-nav-link
  30 + - if @issue.milestone
  31 + |
  32 + = link_to project_milestone_path(@project, @issue.milestone) do
  33 + <strong>Milestone:</strong>
  34 + = @issue.milestone.title
30 35
31 .ui-box.ui-box-show 36 .ui-box.ui-box-show
32 .ui-box-head 37 .ui-box-head
@@ -39,21 +44,7 @@ @@ -39,21 +44,7 @@
39 44
40 .ui-box-body 45 .ui-box-body
41 %cite.cgray 46 %cite.cgray
42 - Created by #{link_to_member(@project, @issue.author)}  
43 - - if @issue.assignee  
44 - \ and currently assigned to #{link_to_member(@project, @issue.assignee)}  
45 -  
46 - - if @issue.milestone  
47 - - milestone = @issue.milestone  
48 - %cite.cgray and attached to milestone  
49 - %strong= link_to_gfm truncate(milestone.title, length: 20), project_milestone_path(milestone.project, milestone)  
50 -  
51 - .pull-right  
52 - - @issue.labels.each do |label|  
53 - %span{class: "label #{label_css_class(label.name)}"}  
54 - %i.icon-tag  
55 - = label.name  
56 - &nbsp; 47 + = render partial: 'issue_context', locals: { issue: @issue }
57 48
58 - if @issue.description.present? 49 - if @issue.description.present?
59 .ui-box-bottom 50 .ui-box-bottom
@@ -73,4 +64,4 @@ @@ -73,4 +64,4 @@
73 - @issue.participants.each do |participant| 64 - @issue.participants.each do |participant|
74 = link_to_member(@project, participant, name: false, size: 24) 65 = link_to_member(@project, participant, name: false, size: 24)
75 66
76 -.voting_notes#notes= render "projects/notes/notes_with_form"  
77 \ No newline at end of file 67 \ No newline at end of file
  68 +.voting_notes#notes= render "projects/notes/notes_with_form"
app/views/projects/issues/update.js.haml
@@ -2,3 +2,12 @@ @@ -2,3 +2,12 @@
2 - if @issue.valid? 2 - if @issue.valid?
3 :plain 3 :plain
4 $("##{dom_id(@issue)}").fadeOut(); 4 $("##{dom_id(@issue)}").fadeOut();
  5 +- elsif params[:issue_context]
  6 + $('.ui-box-body').html("#{escape_javascript(render partial: 'issue_context', locals: { issue: @issue })}");
  7 + $('.ui-box-body').effect('highlight');
  8 + $('.chosen').chosen();
  9 + $('.edit-issue.inline-update input[type="submit"]').hide();
  10 + - if @issue.milestone
  11 + $('.milestone-nav-link').replaceWith("#{escape_javascript(link_to "| #{@issue.milestone.title}", project_milestone_path(@issue.project, @issue.milestone), :class => 'milestone-nav-link')}")
  12 + - else
  13 + $('.milestone-nav-link').html('')
spec/features/issues_spec.rb
@@ -175,6 +175,84 @@ describe &quot;Issues&quot; do @@ -175,6 +175,84 @@ describe &quot;Issues&quot; do
175 end 175 end
176 end 176 end
177 177
  178 + describe 'update assignee from issue#show' do
  179 + let(:issue) { create(:issue, project: project, author: @user) }
  180 +
  181 + context 'by autorized user' do
  182 +
  183 + it 'with dropdown menu' do
  184 + visit project_issue_path(project, issue)
  185 +
  186 + find('.edit-issue.inline-update').select(project.team.members.first.name, from: 'issue_assignee_id')
  187 + click_button 'Update Issue'
  188 +
  189 + page.should have_content "currently assigned to"
  190 + page.has_select?('issue_assignee_id', :selected => project.team.members.first.name)
  191 + end
  192 + end
  193 +
  194 + context 'by unauthorized user' do
  195 +
  196 + let(:guest) { create(:user) }
  197 +
  198 + before :each do
  199 + project.team << [[guest], :guest]
  200 + issue.assignee = @user
  201 + issue.save
  202 + end
  203 +
  204 + it 'shows assignee text' do
  205 + logout
  206 + login_with guest
  207 +
  208 + visit project_issue_path(project, issue)
  209 + page.should have_content "currently assigned to #{issue.assignee.name}"
  210 +
  211 + end
  212 + end
  213 +
  214 + end
  215 +
  216 + describe 'update milestone from issue#show' do
  217 + let!(:issue) { create(:issue, project: project, author: @user) }
  218 + let!(:milestone) { create(:milestone, project: project) }
  219 +
  220 + context 'by authorized user' do
  221 +
  222 + it 'with dropdown menu' do
  223 + visit project_issue_path(project, issue)
  224 +
  225 + p find('.edit-issue.inline-update').text
  226 +
  227 + find('.edit-issue.inline-update').select(milestone.title, from: 'issue_milestone_id')
  228 + click_button 'Update Issue'
  229 +
  230 + page.should have_content "and attached to milestone"
  231 + page.has_select?('issue_assignee_id', :selected => milestone.title)
  232 + end
  233 + end
  234 +
  235 + context 'by unauthorized user' do
  236 +
  237 + let(:guest) { create(:user) }
  238 +
  239 + before :each do
  240 + project.team << [[guest], :guest]
  241 + issue.milestone = milestone
  242 + issue.save
  243 + end
  244 +
  245 + it 'shows milestone text' do
  246 + logout
  247 + login_with guest
  248 +
  249 + visit project_issue_path(project, issue)
  250 +
  251 + page.should have_content "attached to milestone #{milestone.title}"
  252 + end
  253 + end
  254 + end
  255 +
178 def first_issue 256 def first_issue
179 all("ul.issues-list li").first.text 257 all("ul.issues-list li").first.text
180 end 258 end