diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-17 00:09:48 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-17 00:09:48 +0300 |
commit | 9b8433e5ecd54f93ee8df3bb9d9038e978d57afc (patch) | |
tree | b94758d475fe9ffe547eb838fbf15b3910234426 /app/assets/javascripts/vue_merge_request_widget | |
parent | dbfedde341ef6434d40c4c2495f2be751f8bb973 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget')
4 files changed, 100 insertions, 25 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue index 7a00838f95e..4163d195e0f 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue @@ -1,5 +1,5 @@ <script> -import { GlButton } from '@gitlab/ui'; +import { GlButton, GlSprintf, GlLink } from '@gitlab/ui'; import createFlash from '~/flash'; import { BV_SHOW_MODAL } from '~/lib/utils/constants'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; @@ -11,9 +11,11 @@ import eventHub from '../../event_hub'; import approvalsMixin from '../../mixins/approvals'; import MrWidgetContainer from '../mr_widget_container.vue'; import MrWidgetIcon from '../mr_widget_icon.vue'; +import { INVALID_RULES_DOCS_PATH } from '../../constants'; import ApprovalsSummary from './approvals_summary.vue'; import ApprovalsSummaryOptional from './approvals_summary_optional.vue'; import { FETCH_LOADING, FETCH_ERROR, APPROVE_ERROR, UNAPPROVE_ERROR } from './messages'; +import { humanizeInvalidApproversRules } from './humanized_text'; export default { name: 'MRWidgetApprovals', @@ -23,6 +25,8 @@ export default { ApprovalsSummary, ApprovalsSummaryOptional, GlButton, + GlSprintf, + GlLink, }, mixins: [approvalsMixin, glFeatureFlagsMixin()], props: { @@ -78,6 +82,15 @@ export default { approvals() { return this.mr.approvals || {}; }, + invalidRules() { + return this.approvals.invalid_approvers_rules || []; + }, + hasInvalidRules() { + return this.approvals.merge_request_approvers_available && this.invalidRules.length; + }, + invalidRulesText() { + return humanizeInvalidApproversRules(this.invalidRules); + }, approvedBy() { return this.approvals.approved_by ? this.approvals.approved_by.map((x) => x.user) : []; }, @@ -117,6 +130,11 @@ export default { return null; }, + pluralizedRuleText() { + return this.invalidRules.length > 1 + ? this.$options.i18n.invalidRulesPlural + : this.$options.i18n.invalidRuleSingular; + }, }, created() { this.refreshApprovals() @@ -193,6 +211,16 @@ export default { }, }, FETCH_LOADING, + linkToInvalidRules: INVALID_RULES_DOCS_PATH, + i18n: { + invalidRuleSingular: s__( + 'mrWidget|Approval rule %{rules} is invalid. GitLab has approved this rule automatically to unblock the merge request. %{link}', + ), + invalidRulesPlural: s__( + 'mrWidget|Approval rules %{rules} are invalid. GitLab has approved these rules automatically to unblock the merge request. %{link}', + ), + learnMore: __('Learn more.'), + }, }; </script> <template> @@ -201,29 +229,45 @@ export default { <mr-widget-icon name="approval" /> <div v-if="fetchingApprovals">{{ $options.FETCH_LOADING }}</div> <template v-else> - <gl-button - v-if="action" - :variant="action.variant" - :category="action.category" - :loading="isApproving" - class="mr-3" - data-qa-selector="approve_button" - @click="action.action" - > - {{ action.text }} - </gl-button> - <approvals-summary-optional - v-if="isOptional" - :can-approve="hasAction" - :help-path="mr.approvalsHelpPath" - /> - <approvals-summary - v-else - :approved="isApproved" - :approvals-left="approvals.approvals_left || 0" - :rules-left="approvals.approvalRuleNamesLeft" - :approvers="approvedBy" - /> + <div class="gl-display-flex gl-flex-direction-column"> + <div class="gl-display-flex gl-flex-direction-row gl-align-items-center"> + <gl-button + v-if="action" + :variant="action.variant" + :category="action.category" + :loading="isApproving" + class="gl-mr-5" + data-qa-selector="approve_button" + @click="action.action" + > + {{ action.text }} + </gl-button> + <approvals-summary-optional + v-if="isOptional" + :can-approve="hasAction" + :help-path="mr.approvalsHelpPath" + /> + <approvals-summary + v-else + :approved="isApproved" + :approvals-left="approvals.approvals_left || 0" + :rules-left="approvals.approvalRuleNamesLeft" + :approvers="approvedBy" + /> + </div> + <div v-if="hasInvalidRules" class="gl-text-gray-400 gl-mt-2" data-testid="invalid-rules"> + <gl-sprintf :message="pluralizedRuleText"> + <template #rules> + {{ invalidRulesText }} + </template> + <template #link> + <gl-link :href="$options.linkToInvalidRules" target="_blank"> + {{ $options.i18n.learnMore }} + </gl-link> + </template> + </gl-sprintf> + </div> + </div> <slot :is-approving="isApproving" :approve-with-auth="approveWithAuth" diff --git a/app/assets/javascripts/vue_merge_request_widget/components/approvals/humanized_text.js b/app/assets/javascripts/vue_merge_request_widget/components/approvals/humanized_text.js new file mode 100644 index 00000000000..6689d070053 --- /dev/null +++ b/app/assets/javascripts/vue_merge_request_widget/components/approvals/humanized_text.js @@ -0,0 +1,23 @@ +import { __ } from '~/locale'; + +const humanizeRules = (invalidRules) => { + if (invalidRules.length > 1) { + return invalidRules.reduce((rules, { name }, index) => { + if (index === invalidRules.length - 1) { + return `${rules}${__(' and ')}"${name}"`; + } + return rules ? `${rules}, "${name}"` : `"${name}"`; + }, ''); + } + return `"${invalidRules[0].name}"`; +}; + +export const humanizeInvalidApproversRules = (invalidRules) => { + const ruleCount = invalidRules.length; + + if (!ruleCount) { + return ''; + } + + return humanizeRules(invalidRules); +}; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_icon.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_icon.vue index 472df8e3110..437342bf438 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_icon.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_icon.vue @@ -13,7 +13,7 @@ export default { </script> <template> - <div class="circle-icon-container gl-mr-3 align-self-start align-self-lg-center"> + <div class="circle-icon-container gl-mr-3 align-self-start"> <gl-icon :name="name" :size="24" /> </div> </template> diff --git a/app/assets/javascripts/vue_merge_request_widget/constants.js b/app/assets/javascripts/vue_merge_request_widget/constants.js index 533bb38a88c..2c770392acf 100644 --- a/app/assets/javascripts/vue_merge_request_widget/constants.js +++ b/app/assets/javascripts/vue_merge_request_widget/constants.js @@ -1,4 +1,5 @@ import { s__ } from '~/locale'; +import { helpPagePath } from '~/helpers/help_page_helper'; import { stateToComponentMap as classStateMap, stateKey } from './stores/state_maps'; export const SUCCESS = 'success'; @@ -166,3 +167,10 @@ export const EXTENSION_SUMMARY_FAILED_CLASS = 'gl-text-red-500'; export const EXTENSION_SUMMARY_NEUTRAL_CLASS = 'gl-text-gray-700'; export { STATE_MACHINE }; + +export const INVALID_RULES_DOCS_PATH = helpPagePath( + 'user/project/merge_requests/approvals/index.md', + { + anchor: 'invalid-rules', + }, +); |