Commit e373e4fd authored by Igor Drozdov's avatar Igor Drozdov

Merge branch 'ph/230991/displayConflictsAlertInDiffs' into 'master'

Display merge conflicts message when comparing against head

Closes #230991

See merge request gitlab-org/gitlab!39306
parents 9685f862 4c2156a6
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
import { GlLoadingIcon, GlButtonGroup, GlButton } from '@gitlab/ui';
import { GlLoadingIcon, GlButtonGroup, GlButton, GlAlert } from '@gitlab/ui';
import Mousetrap from 'mousetrap';
import { __ } from '~/locale';
import createFlash from '~/flash';
import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils';
import PanelResizer from '~/vue_shared/components/panel_resizer.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { isSingleViewStyle } from '~/helpers/diffs_helper';
......@@ -38,6 +39,7 @@ export default {
PanelResizer,
GlButtonGroup,
GlButton,
GlAlert,
},
mixins: [glFeatureFlagsMixin()],
props: {
......@@ -133,6 +135,9 @@ export default {
'startVersion',
'currentDiffFileId',
'isTreeLoaded',
'conflictResolutionPath',
'canMerge',
'hasConflicts',
]),
...mapGetters('diffs', ['isParallelView', 'currentDiffIndex']),
...mapGetters(['isNotesFetched', 'getNoteableData']),
......@@ -161,6 +166,9 @@ export default {
isLimitedContainer() {
return !this.showTreeList && !this.isParallelView && !this.isFluidLayout;
},
isDiffHead() {
return parseBoolean(getParameterByName('diff_head'));
},
},
watch: {
commit(newCommit, oldCommit) {
......@@ -422,6 +430,49 @@ export default {
:email-patch-path="emailPatchPath"
/>
<div
v-if="isDiffHead && hasConflicts"
:class="{
[CENTERED_LIMITED_CONTAINER_CLASSES]: isLimitedContainer,
}"
>
<gl-alert
:dismissible="false"
:title="__('There are merge conflicts')"
variant="warning"
class="w-100 mb-3"
>
<p class="mb-1">
{{ __('The comparison view may be inaccurate due to merge conflicts.') }}
</p>
<p class="mb-0">
{{
__(
'Resolve these conflicts or ask someone with write access to this repository to merge it locally.',
)
}}
</p>
<template #actions>
<gl-button
v-if="conflictResolutionPath"
:href="conflictResolutionPath"
variant="info"
class="mr-3 gl-alert-action"
>
{{ __('Resolve conflicts') }}
</gl-button>
<gl-button
v-if="canMerge"
class="gl-alert-action"
data-toggle="modal"
data-target="#modal_merge_info"
>
{{ __('Merge locally') }}
</gl-button>
</template>
</gl-alert>
</div>
<div
:data-can-create-note="getNoteableData.current_user.can_create_note"
class="files d-flex"
......
......@@ -41,7 +41,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
def diffs_metadata
diffs = @compare.diffs(diff_options)
render json: DiffsMetadataSerializer.new(project: @merge_request.project)
render json: DiffsMetadataSerializer.new(project: @merge_request.project, current_user: current_user)
.represent(diffs, additional_attributes)
end
......
......@@ -3,4 +3,23 @@
class DiffsMetadataEntity < DiffsEntity
unexpose :diff_files
expose :raw_diff_files, as: :diff_files, using: DiffFileMetadataEntity
expose :conflict_resolution_path do |_, options|
presenter(options[:merge_request]).conflict_resolution_path
end
expose :has_conflicts do |_, options|
options[:merge_request].cannot_be_merged?
end
expose :can_merge do |_, options|
options[:merge_request].can_be_merged_by?(request.current_user)
end
private
def presenter(merge_request)
@presenters ||= {}
@presenters[merge_request] ||= MergeRequestPresenter.new(merge_request, current_user: request.current_user) # rubocop: disable CodeReuse/Presenter
end
end
- if @merge_request.source_branch_exists?
= render "projects/merge_requests/how_to_merge"
= javascript_tag nonce: true do
:plain
window.gl = window.gl || {};
......
......@@ -12,6 +12,9 @@
.merge-request{ data: { mr_action: mr_action, url: merge_request_path(@merge_request, format: :json), project_path: project_path(@merge_request.project), lock_version: @merge_request.lock_version } }
= render "projects/merge_requests/mr_title"
- if @merge_request.source_branch_exists?
= render "projects/merge_requests/how_to_merge"
.merge-request-details.issuable-details{ data: { id: @merge_request.project.id } }
= render "projects/merge_requests/mr_box"
......
......@@ -14960,6 +14960,9 @@ msgstr ""
msgid "Merge in progress"
msgstr ""
msgid "Merge locally"
msgstr ""
msgid "Merge options"
msgstr ""
......@@ -20798,9 +20801,15 @@ msgstr ""
msgid "Resolve all threads in new issue"
msgstr ""
msgid "Resolve conflicts"
msgstr ""
msgid "Resolve conflicts on source branch"
msgstr ""
msgid "Resolve these conflicts or ask someone with write access to this repository to merge it locally."
msgstr ""
msgid "Resolve thread"
msgstr ""
......@@ -24144,6 +24153,9 @@ msgstr ""
msgid "The commit does not exist"
msgstr ""
msgid "The comparison view may be inaccurate due to merge conflicts."
msgstr ""
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
......@@ -24467,6 +24479,9 @@ msgstr ""
msgid "There are currently no events."
msgstr ""
msgid "There are merge conflicts"
msgstr ""
msgid "There are no %{replicableTypeName} to show"
msgstr ""
......
......@@ -30,6 +30,7 @@ RSpec.describe DiffsMetadataEntity do
:email_patch_path, :plain_diff_path,
:merge_request_diffs, :context_commits,
:definition_path_prefix, :source_branch_exists,
:can_merge, :conflict_resolution_path, :has_conflicts,
# Attributes
:diff_files
)
......
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