diff options
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget/components/merge_checks.vue')
-rw-r--r-- | app/assets/javascripts/vue_merge_request_widget/components/merge_checks.vue | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/merge_checks.vue b/app/assets/javascripts/vue_merge_request_widget/components/merge_checks.vue new file mode 100644 index 00000000000..fa84c0a4a6f --- /dev/null +++ b/app/assets/javascripts/vue_merge_request_widget/components/merge_checks.vue @@ -0,0 +1,129 @@ +<script> +import { GlSkeletonLoader } from '@gitlab/ui'; +import { n__, __, sprintf } from '~/locale'; +import mergeRequestQueryVariablesMixin from '../mixins/merge_request_query_variables'; +import mergeChecksQuery from '../queries/merge_checks.query.graphql'; +import StateContainer from './state_container.vue'; +import BoldText from './bold_text.vue'; + +const COMPONENTS = { + conflicts: () => import('./checks/conflicts.vue'), + default: () => import('./checks/message.vue'), +}; + +export default { + apollo: { + state: { + query: mergeChecksQuery, + skip() { + return !this.mr; + }, + variables() { + return this.mergeRequestQueryVariables; + }, + update: (data) => data?.project?.mergeRequest, + }, + }, + components: { + GlSkeletonLoader, + StateContainer, + BoldText, + }, + mixins: [mergeRequestQueryVariablesMixin], + props: { + mr: { + type: Object, + required: true, + }, + }, + data() { + return { + collapsed: true, + state: {}, + }; + }, + computed: { + isLoading() { + return this.$apollo.queries.state.loading; + }, + statusIcon() { + return this.failedChecks.length ? 'failed' : 'success'; + }, + summaryText() { + if (!this.failedChecks.length) { + return this.state?.userPermissions?.canMerge + ? __('%{boldStart}Ready to merge!%{boldEnd}') + : __( + '%{boldStart}Ready to merge by members who can write to the target branch.%{boldEnd}', + ); + } + + return sprintf( + n__( + '%{boldStart}Merge blocked:%{boldEnd} %{count} check failed', + '%{boldStart}Merge blocked:%{boldEnd} %{count} checks failed', + this.failedChecks.length, + ), + { count: this.failedChecks.length }, + ); + }, + checks() { + return this.state.mergeChecks || []; + }, + failedChecks() { + return this.checks.filter((c) => c.result === 'failed'); + }, + }, + methods: { + toggleCollapsed() { + this.collapsed = !this.collapsed; + }, + checkComponent(check) { + return COMPONENTS[check.identifier] || COMPONENTS.default; + }, + }, +}; +</script> + +<template> + <div> + <state-container + :is-loading="isLoading" + :status="statusIcon" + is-collapsible + collapse-on-desktop + :collapsed="collapsed" + :expand-details-tooltip="__('Expand merge checks')" + :collapse-details-tooltip="__('Collapse merge checks')" + @toggle="toggleCollapsed" + > + <template v-if="isLoading" #loading> + <gl-skeleton-loader :width="334" :height="24"> + <rect x="0" y="0" width="24" height="24" rx="4" /> + <rect x="32" y="2" width="302" height="20" rx="4" /> + </gl-skeleton-loader> + </template> + <template v-else> + <bold-text :message="summaryText" /> + </template> + </state-container> + <div + v-if="!collapsed" + class="gl-border-t-1 gl-border-t-solid gl-border-gray-100 gl-relative gl-bg-gray-10" + data-testid="merge-checks-full" + > + <div class="gl-px-5"> + <component + :is="checkComponent(check)" + v-for="(check, index) in checks" + :key="index" + :class="{ + 'gl-border-b-solid gl-border-b-1 gl-border-gray-100': index !== checks.length - 1, + }" + :check="check" + :mr="mr" + /> + </div> + </div> + </div> +</template> |