Commit 3bf38888 authored by Samantha Ming's avatar Samantha Ming

Display which approval rules match a given reviewer

Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/233736
parent cb2b3395
......@@ -49,6 +49,7 @@ function UsersSelect(currentUser, els, options = {}) {
options.todoStateFilter = $dropdown.data('todoStateFilter');
options.iid = $dropdown.data('iid');
options.issuableType = $dropdown.data('issuableType');
options.targetBranch = $dropdown.data('targetBranch');
const showNullUser = $dropdown.data('nullUser');
const defaultNullUser = $dropdown.data('nullUserDefault');
const showMenuAbove = $dropdown.data('showMenuAbove');
......@@ -582,7 +583,14 @@ function UsersSelect(currentUser, els, options = {}) {
img = `<img src='${avatar}' class='avatar avatar-inline m-0' width='32' />`;
}
return userSelect.renderRow(options.issuableType, user, selected, username, img);
return userSelect.renderRow(
options.issuableType,
user,
selected,
username,
img,
elsClassName,
);
},
});
});
......@@ -746,8 +754,16 @@ UsersSelect.prototype.users = function(query, options, callback) {
...getAjaxUsersSelectParams(options, AJAX_USERS_SELECT_PARAMS_MAP),
};
if (options.issuableType === 'merge_request') {
if (
options.issuableType === 'merge_request' ||
(!options.issuableType && (options.iid || options.targetBranch))
) {
params.merge_request_iid = options.iid || null;
params.approval_rules = true;
if (!options.iid) {
params.target_branch = options.targetBranch || null;
}
}
return axios.get(url, { params }).then(({ data }) => {
......@@ -762,7 +778,14 @@ UsersSelect.prototype.buildUrl = function(url) {
return url;
};
UsersSelect.prototype.renderRow = function(issuableType, user, selected, username, img) {
UsersSelect.prototype.renderRow = function(
issuableType,
user,
selected,
username,
img,
elsClassName,
) {
const tooltip = issuableType === 'merge_request' && !user.can_merge ? __('Cannot merge') : '';
const tooltipClass = tooltip ? `has-tooltip` : '';
const selectedClass = selected === true ? 'is-active' : '';
......@@ -776,10 +799,15 @@ UsersSelect.prototype.renderRow = function(issuableType, user, selected, usernam
<a href="#" class="dropdown-menu-user-link d-flex align-items-center ${linkClasses}" ${tooltipAttributes}>
${this.renderRowAvatar(issuableType, user, img)}
<span class="d-flex flex-column overflow-hidden">
<strong class="dropdown-menu-user-full-name">
<strong class="dropdown-menu-user-full-name gl-font-weight-bold">
${escape(user.name)}
</strong>
${username ? `<span class="dropdown-menu-user-username">${username}</span>` : ''}
${
username
? `<span class="dropdown-menu-user-username text gl-text-gray-400">${username}</span>`
: ''
}
${this.renderApprovalRules(elsClassName, user.applicable_approval_rules)}
</span>
</a>
</li>
......@@ -802,4 +830,21 @@ UsersSelect.prototype.renderRowAvatar = function(issuableType, user, img) {
</span>`;
};
UsersSelect.prototype.renderApprovalRules = function(elsClassName, approvalRules = []) {
if (!elsClassName?.includes('reviewer')) {
return '';
}
const count = approvalRules.length;
const [rule] = approvalRules;
const countText = sprintf(__('(+%{count}&nbsp;rules)'), { count });
const renderApprovalRulesCount = count > 1 ? `<span class="ml-1">${countText}</span>` : '';
return count
? `<div class="gl-display-flex gl-font-sm">
<span class="gl-text-truncate" title="${rule.name}">${rule.name}</span>
${renderApprovalRulesCount}
</div>`
: '';
};
export default UsersSelect;
......@@ -55,7 +55,7 @@ module FormHelper
dropdown_data
end
def reviewers_dropdown_options(issuable_type)
def reviewers_dropdown_options(issuable_type, iid = nil, target_branch = nil)
dropdown_data = {
toggle_class: 'js-reviewer-search js-multiselect js-save-user-data',
title: 'Request review from',
......@@ -78,6 +78,14 @@ module FormHelper
}
}
if iid
dropdown_data[:data][:iid] = iid
end
if target_branch
dropdown_data[:data][:target_branch] = target_branch
end
if merge_request_supports_multiple_reviewers?
dropdown_data = multiple_reviewers_dropdown_options(dropdown_data)
end
......
......@@ -7,6 +7,6 @@
- if issuable.reviewers.empty?
= hidden_field_tag "#{issuable.to_ability_name}[reviewer_ids][]", 0, id: nil, data: { meta: '' }
= dropdown_tag(users_dropdown_label(issuable.reviewers), options: reviewers_dropdown_options(issuable.to_ability_name))
= dropdown_tag(users_dropdown_label(issuable.reviewers), options: reviewers_dropdown_options(issuable.to_ability_name, issuable.iid, issuable.target_branch))
- if Feature.enabled?(:mr_collapsed_approval_rules, @project)
= render_if_exists 'shared/issuable/approver_suggestion', issuable: issuable, presenter: presenter
---
title: Display approval rules in reviewer dropdown
merge_request: 46738
author:
type: added
......@@ -10,4 +10,28 @@ RSpec.describe 'Merge request > User edits MR with multiple reviewers' do
end
it_behaves_like 'multiple reviewers merge request', 'updates', 'Save changes'
context 'user approval rules', :js do
let(:rule_name) { 'some-custom-rule' }
let(:user) { create(:admin) }
let!(:mr_rule) { create(:approval_merge_request_rule, merge_request: merge_request, users: [user], name: rule_name, approvals_required: 1 )}
it 'is not shown in assignee dropdown' do
find('.js-assignee-search').click
wait_for_requests
page.within '.dropdown-menu-assignee' do
expect(page).not_to have_content(rule_name)
end
end
it 'is shown in reviewer dropdown' do
find('.js-reviewer-search').click
wait_for_requests
page.within '.dropdown-menu-reviewer' do
expect(page).to have_content(rule_name)
end
end
end
end
......@@ -947,6 +947,9 @@ msgstr ""
msgid "(%{value}) has already been taken"
msgstr ""
msgid "(+%{count}&nbsp;rules)"
msgstr ""
msgid "(No changes)"
msgstr ""
......
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