Commit a1f77871 authored by Samantha Ming's avatar Samantha Ming

Update to use feature flag

- Add feature flag on BE
- Update component & test to use feature flag
parent 1196031b
...@@ -38,6 +38,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -38,6 +38,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:batch_suggestions, @project, default_enabled: true) push_frontend_feature_flag(:batch_suggestions, @project, default_enabled: true)
push_frontend_feature_flag(:auto_expand_collapsed_diffs, @project, default_enabled: true) push_frontend_feature_flag(:auto_expand_collapsed_diffs, @project, default_enabled: true)
push_frontend_feature_flag(:hide_jump_to_next_unresolved_in_threads, @project) push_frontend_feature_flag(:hide_jump_to_next_unresolved_in_threads, @project)
push_frontend_feature_flag(:approvals_commented_by, @project, default_enabled: true)
end end
before_action do before_action do
......
...@@ -6,6 +6,7 @@ import { RULE_TYPE_CODE_OWNER, RULE_TYPE_ANY_APPROVER } from 'ee/approvals/const ...@@ -6,6 +6,7 @@ import { RULE_TYPE_CODE_OWNER, RULE_TYPE_ANY_APPROVER } from 'ee/approvals/const
import { sprintf, __, s__ } from '~/locale'; import { sprintf, __, s__ } from '~/locale';
import UserAvatarList from '~/vue_shared/components/user_avatar/user_avatar_list.vue'; import UserAvatarList from '~/vue_shared/components/user_avatar/user_avatar_list.vue';
import ApprovedIcon from './approved_icon.vue'; import ApprovedIcon from './approved_icon.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default { export default {
components: { components: {
...@@ -14,6 +15,7 @@ export default { ...@@ -14,6 +15,7 @@ export default {
ApprovalCheckRulePopover, ApprovalCheckRulePopover,
EmptyRuleName, EmptyRuleName,
}, },
mixins: [glFeatureFlagsMixin()],
props: { props: {
approvalRules: { approvalRules: {
type: Array, type: Array,
...@@ -92,12 +94,15 @@ export default { ...@@ -92,12 +94,15 @@ export default {
<template> <template>
<table class="table m-0"> <table class="table m-0">
<thead class="thead-white text-nowrap"> <thead class="thead-white text-nowrap">
<tr class="d-none d-md-table-row"> <tr
:class="glFeatures.approvalsCommentedBy ? 'd-md-table-row' : 'd-sm-table-row'"
class="d-none"
>
<th class="w-0"></th> <th class="w-0"></th>
<th class="w-25">{{ s__('MRApprovals|Approvers') }}</th> <th class="w-25">{{ s__('MRApprovals|Approvers') }}</th>
<th class="w-50"></th> <th class="w-50"></th>
<th>{{ s__('MRApprovals|Approvals') }}</th> <th>{{ s__('MRApprovals|Approvals') }}</th>
<th>{{ s__('MRApprovals|Commented by') }}</th> <th v-if="glFeatures.approvalsCommentedBy">{{ s__('MRApprovals|Commented by') }}</th>
<th>{{ s__('MRApprovals|Approved by') }}</th> <th>{{ s__('MRApprovals|Approved by') }}</th>
</tr> </tr>
</thead> </thead>
...@@ -111,7 +116,10 @@ export default { ...@@ -111,7 +116,10 @@ export default {
<tr v-for="rule in rules" :key="rule.id"> <tr v-for="rule in rules" :key="rule.id">
<td class="w-0"><approved-icon :is-approved="rule.approved" /></td> <td class="w-0"><approved-icon :is-approved="rule.approved" /></td>
<td :colspan="rule.rule_type === $options.ruleTypeAnyApprover ? 2 : 1"> <td :colspan="rule.rule_type === $options.ruleTypeAnyApprover ? 2 : 1">
<div class="d-none d-md-block js-name"> <div
:class="glFeatures.approvalsCommentedBy ? 'd-md-block' : 'd-sm-block'"
class="d-none js-name"
>
<empty-rule-name <empty-rule-name
v-if="rule.rule_type === $options.ruleTypeAnyApprover" v-if="rule.rule_type === $options.ruleTypeAnyApprover"
:eligible-approvers-docs-path="eligibleApproversDocsPath" :eligible-approvers-docs-path="eligibleApproversDocsPath"
...@@ -132,7 +140,10 @@ export default { ...@@ -132,7 +140,10 @@ export default {
:security-approvals-help-page-path="securityApprovalsHelpPagePath" :security-approvals-help-page-path="securityApprovalsHelpPagePath"
/> />
</div> </div>
<div class="d-flex d-md-none flex-column js-summary"> <div
:class="glFeatures.approvalsCommentedBy ? 'd-md-none' : 'd-sm-none'"
class="d-flex flex-column js-summary"
>
<empty-rule-name <empty-rule-name
v-if="rule.rule_type === $options.ruleTypeAnyApprover" v-if="rule.rule_type === $options.ruleTypeAnyApprover"
:eligible-approvers-docs-path="eligibleApproversDocsPath" :eligible-approvers-docs-path="eligibleApproversDocsPath"
...@@ -145,7 +156,10 @@ export default { ...@@ -145,7 +156,10 @@ export default {
:img-size="24" :img-size="24"
empty-text="" empty-text=""
/> />
<div v-if="rule.commented_by.length > 0" class="mt-2"> <div
v-if="glFeatures.approvalsCommentedBy && rule.commented_by.length > 0"
class="mt-2"
>
<span>{{ s__('MRApprovals|Commented by') }}</span> <span>{{ s__('MRApprovals|Commented by') }}</span>
<user-avatar-list <user-avatar-list
class="d-inline-block align-middle" class="d-inline-block align-middle"
...@@ -165,14 +179,22 @@ export default { ...@@ -165,14 +179,22 @@ export default {
</td> </td>
<td <td
v-if="rule.rule_type !== $options.ruleTypeAnyApprover" v-if="rule.rule_type !== $options.ruleTypeAnyApprover"
class="d-none d-md-table-cell js-approvers" :class="glFeatures.approvalsCommentedBy ? 'd-md-table-cell' : 'd-sm-table-cell'"
class="d-none js-approvers"
> >
<div><user-avatar-list :items="rule.approvers" :img-size="24" empty-text="" /></div> <div><user-avatar-list :items="rule.approvers" :img-size="24" empty-text="" /></div>
</td> </td>
<td class="w-0 d-none d-md-table-cell text-nowrap js-pending"> <td
:class="glFeatures.approvalsCommentedBy ? 'd-md-table-cell' : 'd-sm-table-cell'"
class="w-0 d-none text-nowrap js-pending"
>
{{ pendingApprovalsText(rule) }} {{ pendingApprovalsText(rule) }}
</td> </td>
<td class="d-none d-md-table-cell js-commented-by"> <td
v-if="glFeatures.approvalsCommentedBy"
:class="glFeatures.approvalsCommentedBy ? 'd-md-table-cell' : 'd-sm-table-cell'"
class="d-none js-commented-by"
>
<user-avatar-list :items="rule.commented_by" :img-size="24" empty-text="" /> <user-avatar-list :items="rule.commented_by" :img-size="24" empty-text="" />
</td> </td>
<td class="d-none d-md-table-cell js-approved-by"> <td class="d-none d-md-table-cell js-approved-by">
......
...@@ -59,9 +59,16 @@ const testRules = () => [testRuleApproved(), testRuleUnapproved(), testRuleOptio ...@@ -59,9 +59,16 @@ const testRules = () => [testRuleApproved(), testRuleUnapproved(), testRuleOptio
describe('EE MRWidget approvals list', () => { describe('EE MRWidget approvals list', () => {
let wrapper; let wrapper;
const createComponent = (props = {}) => { const createComponent = (props = {}, options = {}) => {
const { approvalsCommentedBy = true } = options;
wrapper = shallowMount(ApprovalsList, { wrapper = shallowMount(ApprovalsList, {
propsData: props, propsData: props,
provide: {
glFeatures: {
approvalsCommentedBy,
},
},
}); });
}; };
...@@ -211,7 +218,6 @@ describe('EE MRWidget approvals list', () => { ...@@ -211,7 +218,6 @@ describe('EE MRWidget approvals list', () => {
it('renders commented by list', () => { it('renders commented by list', () => {
const commentedBy = summary.findAll(UserAvatarList).at(1); const commentedBy = summary.findAll(UserAvatarList).at(1);
expect(commentedBy.exists()).toBe(true);
expect(commentedBy.props()).toEqual( expect(commentedBy.props()).toEqual(
expect.objectContaining({ expect.objectContaining({
items: rule.commented_by, items: rule.commented_by,
...@@ -355,4 +361,35 @@ describe('EE MRWidget approvals list', () => { ...@@ -355,4 +361,35 @@ describe('EE MRWidget approvals list', () => {
expect(ruleSection.at(1).text()).toEqual(rule.section); expect(ruleSection.at(1).text()).toEqual(rule.section);
}); });
}); });
describe('approvalsCommentedBy feature flag is off', () => {
let row;
beforeEach(() => {
const rule = testRuleApproved();
createComponent(
{
approvalRules: [rule],
},
{ approvalsCommentedBy: false },
);
row = findRows().at(0);
});
it('does not render commented by in table head', () => {
expect(wrapper.find('thead').text()).not.toContain('Commented by');
});
it('does not render commented by in summary text', () => {
const summary = findRowElement(row, 'summary');
expect(summary.findAll(UserAvatarList).length).toBe(2);
});
it('does not render commented by in user avatar list', () => {
const commentedBy = findRowElement(row, 'commented-by');
expect(commentedBy.exists()).toBe(false);
});
});
}); });
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