diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-21 02:50:22 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-21 02:50:22 +0300 |
commit | 9dc93a4519d9d5d7be48ff274127136236a3adb3 (patch) | |
tree | 70467ae3692a0e35e5ea56bcb803eb512a10bedb /app/assets/javascripts/vue_merge_request_widget | |
parent | 4b0f34b6d759d6299322b3a54453e930c6121ff0 (diff) |
Add latest changes from gitlab-org/gitlab@13-11-stable-eev13.11.0-rc43
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget')
11 files changed, 110 insertions, 82 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_action_button.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_action_button.vue index cc3efae565a..b25c0cc0d96 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_action_button.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_action_button.vue @@ -68,6 +68,7 @@ export default { category="primary" size="small" :title="buttonTitle" + :aria-label="buttonTitle" :loading="isLoading" :disabled="isActionInProgress" :class="`inline gl-ml-2 ${containerClasses}`" diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue index 3419abd4738..1248a891ed9 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue @@ -14,6 +14,7 @@ import { s__, n__ } from '~/locale'; import PipelineMiniGraph from '~/pipelines/components/pipelines_list/pipeline_mini_graph.vue'; import PipelineArtifacts from '~/pipelines/components/pipelines_list/pipelines_artifacts.vue'; import CiIcon from '~/vue_shared/components/ci_icon.vue'; +import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; import { MT_MERGE_STRATEGY } from '../constants'; @@ -28,6 +29,7 @@ export default { GlTooltip, PipelineArtifacts, PipelineMiniGraph, + TimeAgoTooltip, TooltipOnTruncate, LinkedPipelinesMiniList: () => import('ee_component/vue_shared/components/linked_pipelines_mini_list.vue'), @@ -114,6 +116,9 @@ export default { showSourceBranch() { return Boolean(this.pipeline.ref.branch); }, + finishedAt() { + return this.pipeline?.details?.finished_at; + }, coverageDeltaClass() { const delta = this.pipelineCoverageDelta; if (delta && parseFloat(delta) > 0) { @@ -127,10 +132,20 @@ export default { pipelineCoverageJobNumberText() { return n__('from %d job', 'from %d jobs', this.buildsWithCoverage.length); }, + pipelineCoverageTooltipDeltaDescription() { + const delta = parseFloat(this.pipelineCoverageDelta) || 0; + if (delta > 0) { + return s__('Pipeline|This change will increase the overall test coverage if merged.'); + } + if (delta < 0) { + return s__('Pipeline|This change will decrease the overall test coverage if merged.'); + } + return s__('Pipeline|This change will not change the overall test coverage if merged.'); + }, pipelineCoverageTooltipDescription() { return n__( - 'Coverage value for this pipeline was calculated by the coverage value of %d job.', - 'Coverage value for this pipeline was calculated by averaging the resulting coverage values of %d jobs.', + 'Test coverage value for this pipeline was calculated by the coverage value of %d job.', + 'Test coverage value for this pipeline was calculated by averaging the resulting coverage values of %d jobs.', this.buildsWithCoverage.length, ); }, @@ -216,15 +231,24 @@ export default { class="label-branch label-truncate gl-font-weight-normal" /> </template> + <template v-if="finishedAt"> + <time-ago-tooltip + :time="finishedAt" + tooltip-placement="bottom" + data-testid="finished-at" + /> + </template> </div> <div v-if="pipeline.coverage" class="coverage" data-testid="pipeline-coverage"> - {{ s__('Pipeline|Coverage') }} {{ pipeline.coverage }}% + {{ s__('Pipeline|Test coverage') }} {{ pipeline.coverage }}% <span v-if="pipelineCoverageDelta" + ref="pipelineCoverageDelta" :class="coverageDeltaClass" data-testid="pipeline-coverage-delta" - >({{ pipelineCoverageDelta }}%)</span > + ({{ pipelineCoverageDelta }}%) + </span> {{ pipelineCoverageJobNumberText }} <span ref="pipelineCoverageQuestion"> <gl-icon name="question" :size="12" /> @@ -242,6 +266,12 @@ export default { {{ build.name }} ({{ build.coverage }}%) </div> </gl-tooltip> + <gl-tooltip + :target="() => $refs.pipelineCoverageDelta" + data-testid="pipeline-coverage-delta-tooltip" + > + {{ pipelineCoverageTooltipDeltaDescription }} + </gl-tooltip> </div> </div> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue index 84a21a25552..6d68c15cf2d 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue @@ -71,11 +71,11 @@ export default { return (this.glFeatures.mergeRequestWidgetGraphql ? this.state : this.mr).targetBranch; }, shouldRemoveSourceBranch() { - if (this.glFeatures.mergeRequestWidgetGraphql) { - return this.state.shouldRemoveSourceBranch || this.state.forceRemoveSourceBranch; - } + if (!this.glFeatures.mergeRequestWidgetGraphql) return this.mr.shouldRemoveSourceBranch; + + if (!this.state.shouldRemoveSourceBranch) return false; - return this.mr.shouldRemoveSourceBranch; + return this.state.shouldRemoveSourceBranch || this.state.forceRemoveSourceBranch; }, autoMergeStrategy() { return (this.glFeatures.mergeRequestWidgetGraphql ? this.state : this.mr).autoMergeStrategy; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue index 23f415c3116..ee90d734ecb 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue @@ -1,6 +1,5 @@ <script> -import { GlButton, GlModalDirective, GlSkeletonLoader, GlPopover, GlLink } from '@gitlab/ui'; -import { s__ } from '~/locale'; +import { GlButton, GlModalDirective, GlSkeletonLoader } from '@gitlab/ui'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables'; import userPermissionsQuery from '../../queries/permissions.query.graphql'; @@ -13,8 +12,6 @@ export default { GlSkeletonLoader, StatusIcon, GlButton, - GlPopover, - GlLink, }, directives: { GlModalDirective, @@ -93,24 +90,12 @@ export default { return this.mr.sourceBranchProtected; }, - popoverTitle() { - return s__( - 'mrWidget|This feature merges changes from the target branch to the source branch. You cannot use this feature since the source branch is protected.', - ); - }, showResolveButton() { - return this.mr.conflictResolutionPath && this.canPushToSourceBranch; - }, - showPopover() { - return this.showResolveButton && this.sourceBranchProtected; + return ( + this.mr.conflictResolutionPath && this.canPushToSourceBranch && !this.sourceBranchProtected + ); }, }, - i18n: { - title: s__( - 'mrWidget|This feature merges changes from the target branch to the source branch. You cannot use this feature since the source branch is protected.', - ), - linkText: s__('mrWidget|Learn more about resolving conflicts'), - }, }; </script> <template> @@ -141,33 +126,13 @@ export default { }} </span> </span> - <span v-if="showResolveButton" ref="popover"> - <gl-button - :href="mr.conflictResolutionPath" - :disabled="sourceBranchProtected" - data-testid="resolve-conflicts-button" - > - {{ s__('mrWidget|Resolve conflicts') }} - </gl-button> - <gl-popover - v-if="showPopover" - :target="() => $refs.popover" - placement="top" - triggers="hover focus" - > - <template #title> - <div class="gl-font-weight-normal gl-font-base"> - {{ $options.i18n.title }} - </div> - </template> - - <div class="gl-text-center"> - <gl-link :href="mr.conflictsDocsPath" target="_blank" rel="noopener noreferrer"> - {{ $options.i18n.linkText }} - </gl-link> - </div> - </gl-popover> - </span> + <gl-button + v-if="showResolveButton" + :href="mr.conflictResolutionPath" + data-testid="resolve-conflicts-button" + > + {{ s__('mrWidget|Resolve conflicts') }} + </gl-button> <gl-button v-if="canMerge" v-gl-modal-directive="'modal-merge-info'" diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue index 043d14e32a2..9da3bea9362 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue @@ -130,6 +130,7 @@ export default { size="small" category="secondary" variant="warning" + data-qa-selector="revert_button" @click="openRevertModal" > {{ revertLabel }} @@ -151,6 +152,7 @@ export default { v-gl-tooltip.hover :title="cherryPickTitle" size="small" + data-qa-selector="cherry_pick_button" @click="openCherryPickModal" > {{ cherryPickLabel }} diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue index 62c5cd90035..751f8082e1a 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue @@ -15,10 +15,12 @@ import { isEmpty } from 'lodash'; import readyToMergeMixin from 'ee_else_ce/vue_merge_request_widget/mixins/ready_to_merge'; import readyToMergeQuery from 'ee_else_ce/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql'; import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests'; +import createFlash from '~/flash'; +import { secondsToMilliseconds } from '~/lib/utils/datetime_utility'; import simplePoll from '~/lib/utils/simple_poll'; import { __ } from '~/locale'; +import SmartInterval from '~/smart_interval'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import { deprecatedCreateFlash as Flash } from '../../../flash'; import MergeRequest from '../../../merge_request'; import { AUTO_MERGE_STRATEGIES, DANGER, INFO, WARNING } from '../../constants'; import eventHub from '../../event_hub'; @@ -52,20 +54,27 @@ export default { }, manual: true, result({ data }) { + if (Object.keys(this.state).length === 0) { + this.removeSourceBranch = + data.project.mergeRequest.shouldRemoveSourceBranch || + data.project.mergeRequest.forceRemoveSourceBranch || + false; + this.commitMessage = data.project.mergeRequest.defaultMergeCommitMessage; + this.squashBeforeMerge = data.project.mergeRequest.squashOnMerge; + this.isSquashReadOnly = data.project.squashReadOnly; + this.squashCommitMessage = data.project.mergeRequest.defaultSquashCommitMessage; + } + this.state = { ...data.project.mergeRequest, mergeRequestsFfOnlyEnabled: data.project.mergeRequestsFfOnlyEnabled, onlyAllowMergeIfPipelineSucceeds: data.project.onlyAllowMergeIfPipelineSucceeds, }; - this.removeSourceBranch = - data.project.mergeRequest.shouldRemoveSourceBranch || - data.project.mergeRequest.forceRemoveSourceBranch || - false; - this.commitMessage = data.project.mergeRequest.defaultMergeCommitMessage; - this.squashBeforeMerge = data.project.mergeRequest.squashOnMerge; - this.isSquashReadOnly = data.project.squashReadOnly; - this.squashCommitMessage = data.project.mergeRequest.defaultSquashCommitMessage; this.loading = false; + + if (this.state.mergeTrainsCount !== null && this.state.mergeTrainsCount !== undefined) { + this.initPolling(); + } }, }, }, @@ -124,7 +133,7 @@ export default { }, pipeline() { if (this.glFeatures.mergeRequestWidgetGraphql) { - return this.state.pipelines?.nodes?.[0]; + return this.state.headPipeline; } return this.mr.pipeline; @@ -291,8 +300,23 @@ export default { if (this.glFeatures.mergeRequestWidgetGraphql) { eventHub.$off('ApprovalUpdated', this.updateGraphqlState); } + + if (this.pollingInterval) { + this.pollingInterval.destroy(); + } }, methods: { + initPolling() { + const startingPollInterval = secondsToMilliseconds(5); + + this.pollingInterval = new SmartInterval({ + callback: () => this.$apollo.queries.state.refetch(), + startingInterval: startingPollInterval, + maxInterval: startingPollInterval + secondsToMilliseconds(4 * 60), + hiddenInterval: secondsToMilliseconds(6 * 60), + incrementByFactorOf: 2, + }); + }, updateGraphqlState() { return this.$apollo.queries.state.refetch(); }, @@ -351,7 +375,9 @@ export default { }) .catch(() => { this.isMakingRequest = false; - new Flash(__('Something went wrong. Please try again.')); // eslint-disable-line + createFlash({ + message: __('Something went wrong. Please try again.'), + }); }); }, handleMergeImmediatelyButtonClick() { @@ -402,7 +428,9 @@ export default { } }) .catch(() => { - new Flash(__('Something went wrong while merging this merge request. Please try again.')); // eslint-disable-line + createFlash({ + message: __('Something went wrong while merging this merge request. Please try again.'), + }); stopPolling(); }); }, @@ -432,7 +460,9 @@ export default { } }) .catch(() => { - new Flash(__('Something went wrong while deleting the source branch. Please try again.')); // eslint-disable-line + createFlash({ + message: __('Something went wrong while deleting the source branch. Please try again.'), + }); }); }, }, diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue index 6388b817e46..41b5983ae0c 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue @@ -44,7 +44,8 @@ export default { :checked="value" :disabled="isDisabled" name="squash" - class="qa-squash-checkbox js-squash-checkbox gl-mr-2 gl-display-flex gl-align-items-center" + class="js-squash-checkbox gl-mr-2 gl-display-flex gl-align-items-center" + data-qa-selector="squash_checkbox" :title="tooltipTitle" @change="(checked) => $emit('input', checked)" > diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue index 89b095fbfc1..264ea36137f 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue +++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue @@ -480,6 +480,7 @@ export default { v-if="mr.testResultsPath" class="js-reports-container" :endpoint="mr.testResultsPath" + :head-blob-path="mr.headBlobPath" :pipeline-path="mr.pipeline.path" /> @@ -513,7 +514,7 @@ export default { > {{ s__( - 'mrWidget|Fork merge requests do not create merge request pipelines which validate a post merge result', + 'mrWidget|If the last pipeline ran in the fork project, it may be inaccurate. Before merge, we advise running a pipeline in this project.', ) }} </mr-widget-alert-message> diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql index 13ea07884b1..871aa880b36 100644 --- a/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql +++ b/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql @@ -11,11 +11,10 @@ query getState($projectPath: ID!, $iid: String!) { mergeError mergeStatus mergeableDiscussionsState - pipelines(first: 1) { - nodes { - status - warnings - } + headPipeline { + id + status + warnings } shouldBeRebased sourceBranchExists diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql index 8ee45b05431..367b9ad1cdf 100644 --- a/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql +++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql @@ -30,13 +30,11 @@ fragment ReadyToMerge on Project { message } } - pipelines(first: 1) { - nodes { - id - status - path - active - } + headPipeline { + id + status + path + active } } } diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js index 7ccbd771379..f57b638dd81 100644 --- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js +++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js @@ -60,6 +60,7 @@ export default class MergeRequestStore { this.rebaseInProgress = data.rebase_in_progress; this.mergeRequestDiffsPath = data.diffs_path; this.approvalsWidgetType = data.approvals_widget_type; + this.mergeRequestWidgetPath = data.merge_request_widget_path; if (data.issues_links) { const links = data.issues_links; @@ -163,7 +164,7 @@ export default class MergeRequestStore { setGraphqlData(project) { const { mergeRequest } = project; - const pipeline = mergeRequest.pipelines?.nodes?.[0]; + const pipeline = mergeRequest.headPipeline; this.projectArchived = project.archived; this.onlyAllowMergeIfPipelineSucceeds = project.onlyAllowMergeIfPipelineSucceeds; |