Commit 5405f19baced5972472d5d8bdd6a8c77d59e68ea
Exists in
spb-stable
and in
3 other branches
Merge branch 'feature-issue-actions' of https://github.com/jasonblanchard/gitlabhq into 6-5-dev
Showing
7 changed files
with
140 additions
and
17 deletions
Show diff stats
CHANGELOG
app/assets/javascripts/issues.js.coffee
... | ... | @@ -79,3 +79,9 @@ |
79 | 79 | $("#update_issues_ids").val [] |
80 | 80 | $(".issues_bulk_update").hide() |
81 | 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
... | ... | @@ -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 | 26 | .back-link |
27 | 27 | = link_to project_issues_path(@project) do |
28 | 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 | 36 | .ui-box.ui-box-show |
32 | 37 | .ui-box-head |
... | ... | @@ -39,21 +44,7 @@ |
39 | 44 | |
40 | 45 | .ui-box-body |
41 | 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 | - | |
47 | + = render partial: 'issue_context', locals: { issue: @issue } | |
57 | 48 | |
58 | 49 | - if @issue.description.present? |
59 | 50 | .ui-box-bottom |
... | ... | @@ -73,4 +64,4 @@ |
73 | 64 | - @issue.participants.each do |participant| |
74 | 65 | = link_to_member(@project, participant, name: false, size: 24) |
75 | 66 | |
76 | -.voting_notes#notes= render "projects/notes/notes_with_form" | |
77 | 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 | 2 | - if @issue.valid? |
3 | 3 | :plain |
4 | 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 "Issues" do |
175 | 175 | end |
176 | 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 | 256 | def first_issue |
179 | 257 | all("ul.issues-list li").first.text |
180 | 258 | end | ... | ... |