diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-06 12:06:21 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-06 12:06:21 +0000 |
commit | 63894d59abd34f76f399d755012cdcd32c5b1103 (patch) | |
tree | ce797c74a93eb5a17c0e906cc7327938dcd2a4a1 /app | |
parent | cd15d0e6c32da7f69689c7cff2e90aeda33b8318 (diff) | |
download | gitlab-ce-63894d59abd34f76f399d755012cdcd32c5b1103.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
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 |