summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-12-06 12:06:21 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-06 12:06:21 +0000
commit63894d59abd34f76f399d755012cdcd32c5b1103 (patch)
treece797c74a93eb5a17c0e906cc7327938dcd2a4a1 /app
parentcd15d0e6c32da7f69689c7cff2e90aeda33b8318 (diff)
downloadgitlab-ce-63894d59abd34f76f399d755012cdcd32c5b1103.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/confirm_danger_modal.js57
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue22
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue3
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js3
-rw-r--r--app/helpers/projects_helper.rb4
-rw-r--r--app/serializers/merge_request_poll_cached_widget_entity.rb4
-rw-r--r--app/views/projects/_visibility_modal.html.haml30
-rw-r--r--app/views/projects/edit.html.haml4
-rw-r--r--app/views/projects/merge_requests/_widget.html.haml1
9 files changed, 102 insertions, 26 deletions
diff --git a/app/assets/javascripts/confirm_danger_modal.js b/app/assets/javascripts/confirm_danger_modal.js
index 1000c310e35..262d501bfba 100644
--- a/app/assets/javascripts/confirm_danger_modal.js
+++ b/app/assets/javascripts/confirm_danger_modal.js
@@ -1,39 +1,54 @@
import $ from 'jquery';
import { rstrip } from './lib/utils/common_utils';
-function openConfirmDangerModal($form, text) {
- const $input = $('.js-confirm-danger-input');
+function openConfirmDangerModal($form, $modal, text) {
+ const $input = $('.js-confirm-danger-input', $modal);
$input.val('');
- $('.js-confirm-text').text(text || '');
- $('#modal-confirm-danger').modal('show');
+ $('.js-confirm-text', $modal).text(text || '');
+ $modal.modal('show');
- const confirmTextMatch = $('.js-confirm-danger-match').text();
- const $submit = $('.js-confirm-danger-submit');
+ const confirmTextMatch = $('.js-confirm-danger-match', $modal).text();
+ const $submit = $('.js-confirm-danger-submit', $modal);
$submit.disable();
$input.focus();
- $('.js-confirm-danger-input')
- .off('input')
- .on('input', function handleInput() {
- const confirmText = rstrip($(this).val());
- if (confirmText === confirmTextMatch) {
- $submit.enable();
- } else {
- $submit.disable();
- }
- });
- $('.js-confirm-danger-submit')
+ $input.off('input').on('input', function handleInput() {
+ const confirmText = rstrip($(this).val());
+ if (confirmText === confirmTextMatch) {
+ $submit.enable();
+ } else {
+ $submit.disable();
+ }
+ });
+ $('.js-confirm-danger-submit', $modal)
.off('click')
.on('click', () => $form.submit());
}
+function getModal($btn) {
+ const $modal = $btn.prev('.modal');
+
+ if ($modal.length) {
+ return $modal;
+ }
+
+ return $('#modal-confirm-danger');
+}
+
export default function initConfirmDangerModal() {
$(document).on('click', '.js-confirm-danger', e => {
- e.preventDefault();
const $btn = $(e.target);
- const $form = $btn.closest('form');
- const text = $btn.data('confirmDangerMessage');
- openConfirmDangerModal($form, text);
+ const checkFieldName = $btn.data('checkFieldName');
+ const checkFieldCompareValue = $btn.data('checkCompareValue');
+ const checkFieldVal = parseInt($(`[name="${checkFieldName}"]`).val(), 10);
+
+ if (!checkFieldName || checkFieldVal < checkFieldCompareValue) {
+ e.preventDefault();
+ const $form = $btn.closest('form');
+ const $modal = getModal($btn);
+ const text = $btn.data('confirmDangerMessage');
+ openConfirmDangerModal($form, $modal, text);
+ }
});
}
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 aa65b16a3c3..65e523715e2 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
@@ -3,8 +3,9 @@ import _ from 'underscore';
import successSvg from 'icons/_icon_status_success.svg';
import warningSvg from 'icons/_icon_status_warning.svg';
import simplePoll from '~/lib/utils/simple_poll';
-import { __ } from '~/locale';
+import { __, sprintf } from '~/locale';
import readyToMergeMixin from 'ee_else_ce/vue_merge_request_widget/mixins/ready_to_merge';
+import { GlIcon } from '@gitlab/ui';
import MergeRequest from '../../../merge_request';
import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
import Flash from '../../../flash';
@@ -24,6 +25,7 @@ export default {
CommitsHeader,
CommitEdit,
CommitMessageDropdown,
+ GlIcon,
},
mixins: [readyToMergeMixin],
props: {
@@ -111,6 +113,18 @@ export default {
shouldShowMergeEdit() {
return !this.mr.ffOnlyEnabled;
},
+ shaMismatchLink() {
+ const href = this.mr.mergeRequestDiffsPath;
+
+ return sprintf(
+ __('New changes were added. %{linkStart}Reload the page to review them%{linkEnd}'),
+ {
+ linkStart: `<a href="${href}">`,
+ linkEnd: '</a>',
+ },
+ false,
+ );
+ },
},
methods: {
updateMergeCommitMessage(includeDescription) {
@@ -123,7 +137,7 @@ export default {
}
const options = {
- sha: this.mr.sha,
+ sha: this.mr.latestSHA || this.mr.sha,
commit_message: this.commitMessage,
auto_merge_strategy: useAutoMerge ? this.mr.preferredAutoMergeStrategy : undefined,
should_remove_source_branch: this.removeSourceBranch === true,
@@ -314,6 +328,10 @@ export default {
</template>
</div>
</div>
+ <div v-if="mr.isSHAMismatch" class="d-flex align-items-center mt-2 js-sha-mismatch">
+ <gl-icon name="warning-solid" class="text-warning mr-1" />
+ <span class="text-warning" v-html="shaMismatchLink"></span>
+ </div>
</div>
</div>
<template v-if="shouldShowMergeControls">
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 31dbddbd21a..4861588992c 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
@@ -25,7 +25,6 @@ import NothingToMergeState from './components/states/nothing_to_merge.vue';
import MissingBranchState from './components/states/mr_widget_missing_branch.vue';
import NotAllowedState from './components/states/mr_widget_not_allowed.vue';
import ReadyToMergeState from './components/states/ready_to_merge.vue';
-import ShaMismatchState from './components/states/sha_mismatch.vue';
import UnresolvedDiscussionsState from './components/states/unresolved_discussions.vue';
import PipelineBlockedState from './components/states/mr_widget_pipeline_blocked.vue';
import PipelineFailedState from './components/states/pipeline_failed.vue';
@@ -63,7 +62,7 @@ export default {
'mr-widget-not-allowed': NotAllowedState,
'mr-widget-missing-branch': MissingBranchState,
'mr-widget-ready-to-merge': ReadyToMergeState,
- 'sha-mismatch': ShaMismatchState,
+ 'sha-mismatch': ReadyToMergeState,
'mr-widget-checking': CheckingState,
'mr-widget-unresolved-discussions': UnresolvedDiscussionsState,
'mr-widget-pipeline-blocked': PipelineBlockedState,
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 7e5b8f14b96..4c178950ec1 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
@@ -48,6 +48,7 @@ export default class MergeRequestStore {
this.commits = data.commits_without_merge_commits || [];
this.squashCommitMessage = data.default_squash_commit_message;
this.rebaseInProgress = data.rebase_in_progress;
+ this.mergeRequestDiffsPath = data.diffs_path;
if (data.issues_links) {
const links = data.issues_links;
@@ -81,6 +82,7 @@ export default class MergeRequestStore {
this.isOpen = data.state === 'opened';
this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false;
this.isSHAMismatch = this.sha !== data.diff_head_sha;
+ this.latestSHA = data.diff_head_sha;
this.canBeMerged = data.can_be_merged || false;
this.isMergeAllowed = data.mergeable || false;
this.mergeOngoing = data.merge_ongoing;
@@ -170,6 +172,7 @@ export default class MergeRequestStore {
this.conflictsDocsPath = data.conflicts_docs_path;
this.ciEnvironmentsStatusPath = data.ci_environments_status_path;
this.securityApprovalsHelpPagePath = data.security_approvals_help_page_path;
+ this.eligibleApproversDocsPath = data.eligible_approvers_docs_path;
}
get isNothingToMergeState() {
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index ff013f3f7ec..c7fdd009edb 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -699,4 +699,8 @@ module ProjectsHelper
def vue_file_list_enabled?
Feature.enabled?(:vue_file_list, @project)
end
+
+ def show_visibility_confirm_modal?(project)
+ project.unlink_forks_upon_visibility_decrease_enabled? && project.visibility_level > Gitlab::VisibilityLevel::PRIVATE && project.forks_count > 0
+ end
end
diff --git a/app/serializers/merge_request_poll_cached_widget_entity.rb b/app/serializers/merge_request_poll_cached_widget_entity.rb
index c7dc8c43a9a..2f8eb6650e8 100644
--- a/app/serializers/merge_request_poll_cached_widget_entity.rb
+++ b/app/serializers/merge_request_poll_cached_widget_entity.rb
@@ -70,6 +70,10 @@ class MergeRequestPollCachedWidgetEntity < IssuableEntity
presenter(merge_request).source_branch_with_namespace_link
end
+ expose :diffs_path do |merge_request|
+ diffs_project_merge_request_path(merge_request.project, merge_request)
+ end
+
private
delegate :current_user, to: :request
diff --git a/app/views/projects/_visibility_modal.html.haml b/app/views/projects/_visibility_modal.html.haml
new file mode 100644
index 00000000000..3ef93a40137
--- /dev/null
+++ b/app/views/projects/_visibility_modal.html.haml
@@ -0,0 +1,30 @@
+- strong_start = "<strong>".html_safe
+- strong_end = "</strong>".html_safe
+
+.modal.js-confirm-project-visiblity{ tabindex: -1 }
+ .modal-dialog
+ .modal-content
+ .modal-header
+ %h3.page-title= _('Reduce this project’s visibility?')
+ %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
+ %span{ "aria-hidden": true }= sprite_icon("close", size: 16)
+ .modal-body
+ %p
+ - if @project.group
+ = _("You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end} in %{strong_start}%{group_name}%{strong_end}.").html_safe % { project_name: @project.name, group_name: @project.group.name, strong_start: strong_start, strong_end: strong_end }
+ - else
+ = _("You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}.").html_safe % { project_name: @project.name, strong_start: strong_start, strong_end: strong_end }
+ %p
+ = _('Once you confirm and press "Reduce project visibility":')
+ %ul
+ %li
+ = ("Current forks will keep their visibility level but their fork relationship with this project will be %{strong_start}removed%{strong_end}.").html_safe % { strong_start: strong_start, strong_end: strong_end }
+ %label{ for: "confirm_path_input" }
+ = ("To confirm, type %{phrase_code}").html_safe % { phrase_code: '<code class="js-confirm-danger-match">%{phrase_name}</code>'.html_safe % { phrase_name: @project.full_path } }
+ .form-group
+ = text_field_tag 'confirm_path_input', '', class: 'form-control js-confirm-danger-input qa-confirm-input'
+ .form-actions.clearfix
+ .pull-right
+ %button.btn.btn-default{ type: "button", "data-dismiss": "modal" }
+ = _('Cancel')
+ = submit_tag _('Reduce project visibility'), class: "btn btn-danger js-confirm-danger-submit qa-confirm-button", disabled: true
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 328fdd0be10..7ad52673137 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -21,7 +21,9 @@
%input{ name: 'update_section', type: 'hidden', value: 'js-shared-permissions' }
%template.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data_json(@project)
.js-project-permissions-form
- = f.submit _('Save changes'), class: "btn btn-success", data: { qa_selector: 'visibility_features_permissions_save_button' }
+ - if show_visibility_confirm_modal?(@project)
+ = render "visibility_modal"
+ = f.submit _('Save changes'), class: "btn btn-success #{('js-confirm-danger' if show_visibility_confirm_modal?(@project))}", data: { qa_selector: 'visibility_features_permissions_save_button', check_field_name: ("project[visibility_level]" if show_visibility_confirm_modal?(@project)), check_compare_value: @project.visibility_level }
%section.qa-merge-request-settings.rspec-merge-request-settings.settings.merge-requests-feature.no-animate#js-merge-request-settings{ class: [('expanded' if expanded), ('hidden' if @project.project_feature.send(:merge_requests_access_level) == 0)] }
.settings-header
diff --git a/app/views/projects/merge_requests/_widget.html.haml b/app/views/projects/merge_requests/_widget.html.haml
index f056189fec0..b00c95c3cd7 100644
--- a/app/views/projects/merge_requests/_widget.html.haml
+++ b/app/views/projects/merge_requests/_widget.html.haml
@@ -9,5 +9,6 @@
window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}';
window.gl.mrWidgetData.troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/index.md', anchor: 'troubleshooting')}';
window.gl.mrWidgetData.security_approvals_help_page_path = '#{help_page_path('user/application_security/index.html', anchor: 'security-approvals-in-merge-requests-ultimate')}';
+ window.gl.mrWidgetData.eligible_approvers_docs_path = '#{help_page_path('user/project/merge_requests/merge_request_approvals', anchor: 'eligible-approvers')}';
#js-vue-mr-widget.mr-widget