Commit df27b3a1 authored by Zeger-Jan van de Weg's avatar Zeger-Jan van de Weg Committed by Zeger-Jan van de Weg

Issuable can be assigned to author

Closes #9014

The only difference with #9014 is that I thoughed the author should also be
able to assign the issue. If this is unwanted behavior Ill revert it.
parent 04d1b412
...@@ -78,6 +78,7 @@ v 8.5.0 (unreleased) ...@@ -78,6 +78,7 @@ v 8.5.0 (unreleased)
- Add label description (Nuttanart Pornprasitsakul) - Add label description (Nuttanart Pornprasitsakul)
- Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul) - Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul)
- Add Todos - Add Todos
- Allow issues and merge requests to be assigned to the author(Zeger-Jan van de Weg)
v 8.4.4 v 8.4.4
- Update omniauth-saml gem to 1.4.2 - Update omniauth-saml gem to 1.4.2
......
...@@ -7,11 +7,12 @@ class @UsersSelect ...@@ -7,11 +7,12 @@ class @UsersSelect
@projectId = $(select).data('project-id') @projectId = $(select).data('project-id')
@groupId = $(select).data('group-id') @groupId = $(select).data('group-id')
@showCurrentUser = $(select).data('current-user') @showCurrentUser = $(select).data('current-user')
@authorId = $(select).data('author-id')
showNullUser = $(select).data('null-user') showNullUser = $(select).data('null-user')
showAnyUser = $(select).data('any-user') showAnyUser = $(select).data('any-user')
showEmailUser = $(select).data('email-user') showEmailUser = $(select).data('email-user')
firstUser = $(select).data('first-user') firstUser = $(select).data('first-user')
$(select).select2 $(select).select2
placeholder: "Search for a user" placeholder: "Search for a user"
multiple: $(select).hasClass('multiselect') multiple: $(select).hasClass('multiselect')
...@@ -112,6 +113,7 @@ class @UsersSelect ...@@ -112,6 +113,7 @@ class @UsersSelect
project_id: @projectId project_id: @projectId
group_id: @groupId group_id: @groupId
current_user: @showCurrentUser current_user: @showCurrentUser
author_id: @authorId
dataType: "json" dataType: "json"
).done (users) -> ).done (users) ->
callback(users) callback(users)
......
...@@ -12,8 +12,14 @@ class AutocompleteController < ApplicationController ...@@ -12,8 +12,14 @@ class AutocompleteController < ApplicationController
if params[:search].blank? if params[:search].blank?
# Include current user if available to filter by "Me" # Include current user if available to filter by "Me"
if params[:current_user] && current_user if params[:current_user] && current_user
@users = [*@users, current_user].uniq @users = [*@users, current_user]
end end
if params[:author_id]
@users = [User.find(params[:author_id]), *@users]
end
@users.uniq!
end end
render json: @users, only: [:name, :username, :id], methods: [:avatar_url] render json: @users, only: [:name, :username, :id], methods: [:avatar_url]
......
...@@ -59,8 +59,8 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -59,8 +59,8 @@ class Projects::IssuesController < Projects::ApplicationController
end end
def show def show
@note = @project.notes.new(noteable: @issue) @note = @project.notes.new(noteable: @issue)
@notes = @issue.notes.nonawards.with_associations.fresh @notes = @issue.notes.nonawards.with_associations.fresh
@noteable = @issue @noteable = @issue
@merge_requests = @issue.referenced_merge_requests(current_user) @merge_requests = @issue.referenced_merge_requests(current_user)
......
...@@ -6,12 +6,13 @@ module SelectsHelper ...@@ -6,12 +6,13 @@ module SelectsHelper
value = opts[:selected] || '' value = opts[:selected] || ''
placeholder = opts[:placeholder] || 'Search for a user' placeholder = opts[:placeholder] || 'Search for a user'
null_user = opts[:null_user] || false null_user = opts[:null_user] || false
any_user = opts[:any_user] || false any_user = opts[:any_user] || false
email_user = opts[:email_user] || false email_user = opts[:email_user] || false
first_user = opts[:first_user] && current_user ? current_user.username : false first_user = opts[:first_user] && current_user ? current_user.username : false
current_user = opts[:current_user] || false current_user = opts[:current_user] || false
project = opts[:project] || @project author_id = opts[:author_id] || false
project = opts[:project] || @project
html = { html = {
class: css_class, class: css_class,
...@@ -21,7 +22,8 @@ module SelectsHelper ...@@ -21,7 +22,8 @@ module SelectsHelper
any_user: any_user, any_user: any_user,
email_user: email_user, email_user: email_user,
first_user: first_user, first_user: first_user,
current_user: current_user current_user: current_user,
author_id: author_id
} }
} }
......
...@@ -116,6 +116,11 @@ module Issuable ...@@ -116,6 +116,11 @@ module Issuable
assignee_id_changed? assignee_id_changed?
end end
def can_assign_user?(current_user)
author == current_user ||
Ability.abilities.allowed?(current_user, :"admin_#{to_ability_name}", project)
end
def open? def open?
opened? || reopened? opened? || reopened?
end end
......
...@@ -33,7 +33,7 @@ class IssuableBaseService < BaseService ...@@ -33,7 +33,7 @@ class IssuableBaseService < BaseService
end end
end end
def filter_params(issuable_ability_name = :issue) def filter_params(issuable_ability_name, issuable)
params[:assignee_id] = "" if params[:assignee_id] == IssuableFinder::NONE params[:assignee_id] = "" if params[:assignee_id] == IssuableFinder::NONE
params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE
...@@ -42,13 +42,18 @@ class IssuableBaseService < BaseService ...@@ -42,13 +42,18 @@ class IssuableBaseService < BaseService
unless can?(current_user, ability, project) unless can?(current_user, ability, project)
params.delete(:milestone_id) params.delete(:milestone_id)
params.delete(:label_ids) params.delete(:label_ids)
params.delete(:assignee_id)
# The author of an issue can be assigned, to signal the ball being in his/her
# court. This allow him/her to reassign the issue back to the reviewer.
if issuable && !(issuable.author == current_user)
params.delete(:assignee_id)
end
end end
end end
def update(issuable) def update(issuable)
change_state(issuable) change_state(issuable)
filter_params filter_params(issuable)
old_labels = issuable.labels.to_a old_labels = issuable.labels.to_a
if params.present? && issuable.update_attributes(params.merge(updated_by: current_user)) if params.present? && issuable.update_attributes(params.merge(updated_by: current_user))
......
...@@ -10,8 +10,8 @@ module Issues ...@@ -10,8 +10,8 @@ module Issues
private private
def filter_params def filter_params(issuable = nil)
super(:issue) super(:issue, issuable)
end end
def execute_hooks(issue, action = 'open') def execute_hooks(issue, action = 'open')
......
...@@ -23,8 +23,8 @@ module MergeRequests ...@@ -23,8 +23,8 @@ module MergeRequests
private private
def filter_params def filter_params(issueable = nil)
super(:merge_request) super(:merge_request, issueable)
end end
end end
end end
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
.title .title
%label %label
Assignee Assignee
- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) - if issuable.can_assign_user?(current_user)
.pull-right .pull-right
= link_to 'Edit', '#', class: 'edit-link' = link_to 'Edit', '#', class: 'edit-link'
.value .value
...@@ -43,7 +43,10 @@ ...@@ -43,7 +43,10 @@
.light None .light None
.selectbox .selectbox
= users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true, current_user: true, first_user: true) = users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]",
placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee',
selected: issuable.assignee_id, project: @target_project, null_user: true, current_user: true,
first_user: true, author_id: issuable.author_id)
.block.milestone .block.milestone
.sidebar-collapsed-icon .sidebar-collapsed-icon
......
...@@ -143,4 +143,17 @@ describe AutocompleteController do ...@@ -143,4 +143,17 @@ describe AutocompleteController do
it { expect(body.size).to eq 0 } it { expect(body.size).to eq 0 }
end end
end end
context 'author of issuable included' do
before do
sign_in(user)
get(:users, author_id: non_member.id)
end
let(:body) { JSON.parse(response.body) }
it 'should also return the author' do
expect(body.first["username"]).to eq non_member.username
end
end
end end
...@@ -111,6 +111,20 @@ describe Issue, "Issuable" do ...@@ -111,6 +111,20 @@ describe Issue, "Issuable" do
end end
end end
describe "#can_assign_user?" do
let(:author) { build(:user) }
let(:issue) { build(:issue, author: author)}
it "Allows the author to change the assignee" do
expect(issue.can_assign_user?(author)).to be_truthy
end
it "Doesn't allow others, non-team members" do
other_user = build(:user)
expect(issue.can_assign_user?(other_user)).to be_falsey
end
end
describe "votes" do describe "votes" do
before do before do
author = create :user author = create :user
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment