Commit b0b43e4f authored by Mark Chao's avatar Mark Chao Committed by Nick Thomas

Enable approval rule schema on approvals action

Similar to what's done on API endpoint.
parent de111c93
...@@ -161,6 +161,7 @@ export default { ...@@ -161,6 +161,7 @@ export default {
{{ action.text }} {{ action.text }}
</gl-button> </gl-button>
<approvals-summary <approvals-summary
:approved="mr.approvals.approved"
:approvals-left="mr.approvals.approvals_left" :approvals-left="mr.approvals.approvals_left"
:rules-left="mr.approvals.approvalRuleNamesLeft" :rules-left="mr.approvals.approvalRuleNamesLeft"
:approvers="approvedBy" :approvers="approvedBy"
......
...@@ -25,9 +25,6 @@ export default { ...@@ -25,9 +25,6 @@ export default {
total: rule.approvals_required, total: rule.approvals_required,
}); });
}, },
isApproved(rule) {
return rule.approvals_required > 0 && rule.approvals_required <= rule.approved_by.length;
},
summaryText(rule) { summaryText(rule) {
return rule.approvals_required === 0 return rule.approvals_required === 0
? this.summaryOptionalText(rule) ? this.summaryOptionalText(rule)
...@@ -63,7 +60,7 @@ export default { ...@@ -63,7 +60,7 @@ export default {
</thead> </thead>
<tbody> <tbody>
<tr v-for="rule in approvalRules" :key="rule.id"> <tr v-for="rule in approvalRules" :key="rule.id">
<td class="w-0"><approved-icon :is-approved="isApproved(rule)" /></td> <td class="w-0"><approved-icon :is-approved="rule.approved" /></td>
<td :colspan="rule.fallback ? 2 : 1"> <td :colspan="rule.fallback ? 2 : 1">
<div class="d-none d-sm-block js-name">{{ rule.name }}</div> <div class="d-none d-sm-block js-name">{{ rule.name }}</div>
<div class="d-flex d-sm-none flex-column js-summary"> <div class="d-flex d-sm-none flex-column js-summary">
......
...@@ -9,6 +9,10 @@ export default { ...@@ -9,6 +9,10 @@ export default {
UserAvatarList, UserAvatarList,
}, },
props: { props: {
approved: {
type: Boolean,
required: true,
},
approvalsLeft: { approvalsLeft: {
type: Number, type: Number,
required: true, required: true,
...@@ -25,11 +29,8 @@ export default { ...@@ -25,11 +29,8 @@ export default {
}, },
}, },
computed: { computed: {
isApproved() {
return this.approvalsLeft <= 0;
},
message() { message() {
if (this.isApproved) { if (this.approved) {
return APPROVED_MESSAGE; return APPROVED_MESSAGE;
} }
......
...@@ -55,8 +55,13 @@ export default class MergeRequestStore extends CEMergeRequestStore { ...@@ -55,8 +55,13 @@ export default class MergeRequestStore extends CEMergeRequestStore {
setApprovals(data) { setApprovals(data) {
this.approvals = mapApprovalsResponse(data); this.approvals = mapApprovalsResponse(data);
this.approvalsLeft = !!data.approvals_left; this.approvalsLeft = !!data.approvals_left;
this.isApproved = !this.approvalsLeft || false; if (gon.features.approvalRules) {
this.preventMerge = this.approvalsRequired && this.approvalsLeft; this.isApproved = data.approved || false;
this.preventMerge = !this.isApproved;
} else {
this.isApproved = !this.approvalsLeft || false;
this.preventMerge = this.approvalsRequired && this.approvalsLeft;
}
} }
setApprovalRules(data) { setApprovalRules(data) {
......
...@@ -9,7 +9,7 @@ module EE ...@@ -9,7 +9,7 @@ module EE
prepended do prepended do
before_action only: [:show] do before_action only: [:show] do
push_frontend_feature_flag(:approval_rules) push_frontend_feature_flag(:approval_rules, merge_request.project)
end end
before_action :whitelist_query_limiting_ee_merge, only: [:merge] before_action :whitelist_query_limiting_ee_merge, only: [:merge]
...@@ -65,7 +65,12 @@ module EE ...@@ -65,7 +65,12 @@ module EE
def render_approvals_json def render_approvals_json
respond_to do |format| respond_to do |format|
format.json do format.json do
entity = EE::API::Entities::MergeRequestApprovals.new(merge_request, current_user: current_user) entity = if ::Feature.enabled?(:approval_rules, merge_request.project)
EE::API::Entities::ApprovalState.new(merge_request.approval_state, current_user: current_user)
else
EE::API::Entities::MergeRequestApprovals.new(merge_request, current_user: current_user)
end
render json: entity render json: entity
end end
end end
......
...@@ -35,7 +35,9 @@ class ApprovalWrappedRule ...@@ -35,7 +35,9 @@ class ApprovalWrappedRule
# - Additional complexity to add update hooks # - Additional complexity to add update hooks
# - DB updating many MRs for one project rule change is inefficient # - DB updating many MRs for one project rule change is inefficient
def approved_approvers def approved_approvers
return approval_rule.approved_approvers if merge_request.merged? if merge_request.merged? && merge_request.merge_jid.nil? # merge process completed
return approval_rule.approved_approvers
end
strong_memoize(:approved_approvers) do strong_memoize(:approved_approvers) do
overall_approver_ids = merge_request.approvals.map(&:user_id) overall_approver_ids = merge_request.approvals.map(&:user_id)
......
...@@ -18,7 +18,8 @@ module ApprovalRules ...@@ -18,7 +18,8 @@ module ApprovalRules
copy_project_approval_rules copy_project_approval_rules
end end
merge_request.approval_rules.each(&:sync_approved_approvers) # TODO: https://gitlab.com/gitlab-org/gitlab-ee/issues/9866
merge_request.approval_rules.reload.each(&:sync_approved_approvers)
end end
end end
......
...@@ -267,6 +267,7 @@ module EE ...@@ -267,6 +267,7 @@ module EE
expose :approved_approvers, as: :approved_by, using: ::API::Entities::UserBasic expose :approved_approvers, as: :approved_by, using: ::API::Entities::UserBasic
expose :code_owner expose :code_owner
expose :source_rule, using: SourceRule expose :source_rule, using: SourceRule
expose :approved?, as: :approved
end end
# Decorates ApprovalState # Decorates ApprovalState
......
...@@ -13,6 +13,7 @@ const testRuleApproved = () => ({ ...@@ -13,6 +13,7 @@ const testRuleApproved = () => ({
approvals_required: 2, approvals_required: 2,
approved_by: [{ id: 1 }, { id: 2 }, { id: 3 }], approved_by: [{ id: 1 }, { id: 2 }, { id: 3 }],
approvers: testApprovers(), approvers: testApprovers(),
approved: true,
}); });
const testRuleUnapproved = () => ({ const testRuleUnapproved = () => ({
id: 2, id: 2,
...@@ -20,6 +21,7 @@ const testRuleUnapproved = () => ({ ...@@ -20,6 +21,7 @@ const testRuleUnapproved = () => ({
approvals_required: 1, approvals_required: 1,
approved_by: [], approved_by: [],
approvers: testApprovers(), approvers: testApprovers(),
approved: false,
}); });
const testRuleOptional = () => ({ const testRuleOptional = () => ({
id: 3, id: 3,
...@@ -27,6 +29,7 @@ const testRuleOptional = () => ({ ...@@ -27,6 +29,7 @@ const testRuleOptional = () => ({
approvals_required: 0, approvals_required: 0,
approved_by: [{ id: 1 }], approved_by: [{ id: 1 }],
approvers: testApprovers(), approvers: testApprovers(),
approved: false,
}); });
const testRuleFallback = () => ({ const testRuleFallback = () => ({
id: 'fallback', id: 'fallback',
...@@ -35,6 +38,7 @@ const testRuleFallback = () => ({ ...@@ -35,6 +38,7 @@ const testRuleFallback = () => ({
approvals_required: 3, approvals_required: 3,
approved_by: [{ id: 1 }, { id: 2 }], approved_by: [{ id: 1 }, { id: 2 }],
approvers: [], approvers: [],
approved: false,
}); });
const testRules = () => [testRuleApproved(), testRuleUnapproved(), testRuleOptional()]; const testRules = () => [testRuleApproved(), testRuleUnapproved(), testRuleOptional()];
......
...@@ -15,6 +15,7 @@ const localVue = createLocalVue(); ...@@ -15,6 +15,7 @@ const localVue = createLocalVue();
const testApprovedBy = () => [1, 7, 10].map(id => ({ id })); const testApprovedBy = () => [1, 7, 10].map(id => ({ id }));
const testApprovals = () => ({ const testApprovals = () => ({
has_approval_rules: true, has_approval_rules: true,
approved: false,
approved_by: testApprovedBy().map(user => ({ user })), approved_by: testApprovedBy().map(user => ({ user })),
approval_rules_left: [], approval_rules_left: [],
approvals_left: 4, approvals_left: 4,
......
...@@ -17,6 +17,7 @@ describe('EE MRWidget approvals summary', () => { ...@@ -17,6 +17,7 @@ describe('EE MRWidget approvals summary', () => {
const createComponent = (props = {}) => { const createComponent = (props = {}) => {
wrapper = shallowMount(localVue.extend(ApprovalsSummary), { wrapper = shallowMount(localVue.extend(ApprovalsSummary), {
propsData: { propsData: {
approved: false,
approvers: testApprovers(), approvers: testApprovers(),
approvalsLeft: TEST_APPROVALS_LEFT, approvalsLeft: TEST_APPROVALS_LEFT,
rulesLeft: testRulesLeft(), rulesLeft: testRulesLeft(),
...@@ -37,7 +38,7 @@ describe('EE MRWidget approvals summary', () => { ...@@ -37,7 +38,7 @@ describe('EE MRWidget approvals summary', () => {
describe('when approved', () => { describe('when approved', () => {
beforeEach(() => { beforeEach(() => {
createComponent({ createComponent({
approvalsLeft: 0, approved: true,
}); });
}); });
......
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