Commit 54bdd83e authored by Phil Hughes's avatar Phil Hughes Committed by Igor Drozdov

Converts widget conflicts state data to GraphQL

Moves the state data used in the conflicts widget state
over to GraphQL.

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/235712
parent dbb363fd
<script>
import $ from 'jquery';
import { escape } from 'lodash';
import { GlButton, GlModalDirective } from '@gitlab/ui';
import { GlButton, GlModalDirective, GlSkeletonLoader } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
import { mouseenter, debouncedMouseleave, togglePopover } from '~/shared/popover';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables';
import StatusIcon from '../mr_widget_status_icon.vue';
import userPermissionsQuery from '../../queries/permissions.query.graphql';
import conflictsStateQuery from '../../queries/states/conflicts.query.graphql';
export default {
name: 'MRWidgetConflicts',
components: {
GlSkeletonLoader,
StatusIcon,
GlButton,
},
directives: {
GlModalDirective,
},
mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
apollo: {
userPermissions: {
query: userPermissionsQuery,
skip() {
return !this.glFeatures.mergeRequestWidgetGraphql;
},
variables() {
return this.mergeRequestQueryVariables;
},
update: data => data.project.mergeRequest.userPermissions,
},
stateData: {
query: conflictsStateQuery,
skip() {
return !this.glFeatures.mergeRequestWidgetGraphql;
},
variables() {
return this.mergeRequestQueryVariables;
},
update: data => data.project.mergeRequest,
},
},
props: {
/* TODO: This is providing all store and service down when it
only needs a few props */
......@@ -24,21 +52,72 @@ export default {
default: () => ({}),
},
},
data() {
return {
userPermissions: {},
stateData: {},
};
},
computed: {
isLoading() {
return (
this.glFeatures.mergeRequestWidgetGraphql &&
this.$apollo.queries.userPermissions.loading &&
this.$apollo.queries.stateData.loading
);
},
canPushToSourceBranch() {
if (this.glFeatures.mergeRequestWidgetGraphql) {
return this.userPermissions.pushToSourceBranch;
}
return this.mr.canPushToSourceBranch;
},
canMerge() {
if (this.glFeatures.mergeRequestWidgetGraphql) {
return this.userPermissions.canMerge;
}
return this.mr.canMerge;
},
shouldBeRebased() {
if (this.glFeatures.mergeRequestWidgetGraphql) {
return this.stateData.shouldBeRebased;
}
return this.mr.shouldBeRebased;
},
sourceBranchProtected() {
if (this.glFeatures.mergeRequestWidgetGraphql) {
return this.stateData.sourceBranchProtected;
}
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.mr.canPushToSourceBranch;
return this.mr.conflictResolutionPath && this.canPushToSourceBranch;
},
showPopover() {
return this.showResolveButton && this.mr.sourceBranchProtected;
return this.showResolveButton && this.sourceBranchProtected;
},
},
mounted() {
if (this.showPopover) {
watch: {
showPopover: {
handler(newVal) {
if (newVal) {
this.$nextTick(this.initPopover);
}
},
immediate: true,
},
},
methods: {
initPopover() {
const $el = $(this.$refs.popover);
$el
......@@ -68,7 +147,7 @@ export default {
.on('show.bs.popover', () => {
window.addEventListener('scroll', togglePopover.bind($el, false), { once: true });
});
}
},
},
};
</script>
......@@ -76,34 +155,41 @@ export default {
<div class="mr-widget-body media">
<status-icon :show-disabled-button="true" status="warning" />
<div class="media-body space-children">
<span v-if="mr.shouldBeRebased" class="bold">
<div v-if="isLoading" class="gl-ml-4 gl-w-full mr-conflict-loader">
<gl-skeleton-loader :width="334" :height="30">
<rect x="0" y="7" width="150" height="16" rx="4" />
<rect x="158" y="7" width="84" height="16" rx="4" />
<rect x="250" y="7" width="84" height="16" rx="4" />
</gl-skeleton-loader>
</div>
<div v-else class="media-body space-children">
<span v-if="shouldBeRebased" class="bold">
{{
s__(`mrWidget|Fast-forward merge is not possible.
To merge this request, first rebase locally.`)
To merge this request, first rebase locally.`)
}}
</span>
<template v-else>
<span class="bold">
{{ s__('mrWidget|There are merge conflicts') }}<span v-if="!mr.canMerge">.</span>
<span v-if="!mr.canMerge">
{{ s__('mrWidget|There are merge conflicts') }}<span v-if="!canMerge">.</span>
<span v-if="!canMerge">
{{
s__(`mrWidget|Resolve these conflicts or ask someone
with write access to this repository to merge it locally`)
with write access to this repository to merge it locally`)
}}
</span>
</span>
<span v-if="showResolveButton" ref="popover">
<gl-button
:href="mr.conflictResolutionPath"
:disabled="mr.sourceBranchProtected"
:href="!sourceBranchProtected && mr.conflictResolutionPath"
:disabled="sourceBranchProtected"
class="js-resolve-conflicts-button"
>
{{ s__('mrWidget|Resolve conflicts') }}
</gl-button>
</span>
<gl-button
v-if="mr.canMerge"
v-if="canMerge"
v-gl-modal-directive="'modal-merge-info'"
class="js-merge-locally-button"
>
......
query userPermissionsQuery($projectPath: ID!, $iid: String!) {
project(fullPath: $projectPath) {
mergeRequest(iid: $iid) {
userPermissions {
canMerge
pushToSourceBranch
}
}
}
}
query workInProgressQuery($projectPath: ID!, $iid: String!) {
project(fullPath: $projectPath) {
mergeRequest(iid: $iid) {
shouldBeRebased
sourceBranchProtected
}
}
}
......@@ -1039,3 +1039,11 @@ $mr-widget-min-height: 69px;
.diff-file-row.is-active {
background-color: $gray-50;
}
.mr-conflict-loader {
max-width: 334px;
> svg {
vertical-align: middle;
}
}
......@@ -49,6 +49,8 @@ module Types
description: 'ID of the merge request target project'
field :source_branch, GraphQL::STRING_TYPE, null: false,
description: 'Source branch of the merge request'
field :source_branch_protected, GraphQL::BOOLEAN_TYPE, null: false, calls_gitaly: true,
description: 'Indicates if the source branch is protected'
field :target_branch, GraphQL::STRING_TYPE, null: false,
description: 'Target branch of the merge request'
field :work_in_progress, GraphQL::BOOLEAN_TYPE, method: :work_in_progress?, null: false,
......@@ -194,6 +196,10 @@ module Types
def commit_count
object&.metrics&.commits_count
end
def source_branch_protected
object.source_project.present? && ProtectedBranch.protected?(object.source_project, object.source_branch)
end
end
end
Types::MergeRequestType.prepend_if_ee('::EE::Types::MergeRequestType')
......@@ -12780,6 +12780,11 @@ type MergeRequest implements CurrentUserTodos & Noteable {
"""
sourceBranchExists: Boolean!
"""
Indicates if the source branch is protected
"""
sourceBranchProtected: Boolean!
"""
Source project of the merge request
"""
......
......@@ -35042,6 +35042,24 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "sourceBranchProtected",
"description": "Indicates if the source branch is protected",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "sourceProject",
"description": "Source project of the merge request",
......@@ -1950,6 +1950,7 @@ Autogenerated return type of MarkAsSpamSnippet.
| `shouldRemoveSourceBranch` | Boolean | Indicates if the source branch of the merge request will be deleted after merge |
| `sourceBranch` | String! | Source branch of the merge request |
| `sourceBranchExists` | Boolean! | Indicates if the source branch of the merge request exists |
| `sourceBranchProtected` | Boolean! | Indicates if the source branch is protected |
| `sourceProject` | Project | Source project of the merge request |
| `sourceProjectId` | Int | ID of the merge request source project |
| `state` | MergeRequestState! | State of the merge request |
......
......@@ -27,7 +27,7 @@ RSpec.describe GitlabSchema.types['MergeRequest'] do
upvotes downvotes head_pipeline pipelines task_completion_status
milestone assignees participants subscribed labels discussion_locked time_estimate
total_time_spent reference author merged_at commit_count current_user_todos
conflicts auto_merge_enabled approved_by
conflicts auto_merge_enabled approved_by source_branch_protected
]
if Gitlab.ee?
......
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