Commit 7243fa00 authored by Phil Hughes's avatar Phil Hughes Committed by Bob Van Landuyt

Show modal before changing project visibility

Shows a confirmation modal before the user changes the
projects visibility.

https://gitlab.com/gitlab-org/gitlab/issues/33358
parent 762862cb
import $ from 'jquery'; import $ from 'jquery';
import { rstrip } from './lib/utils/common_utils'; import { rstrip } from './lib/utils/common_utils';
function openConfirmDangerModal($form, text) { function openConfirmDangerModal($form, $modal, text) {
const $input = $('.js-confirm-danger-input'); const $input = $('.js-confirm-danger-input', $modal);
$input.val(''); $input.val('');
$('.js-confirm-text').text(text || ''); $('.js-confirm-text', $modal).text(text || '');
$('#modal-confirm-danger').modal('show'); $modal.modal('show');
const confirmTextMatch = $('.js-confirm-danger-match').text(); const confirmTextMatch = $('.js-confirm-danger-match', $modal).text();
const $submit = $('.js-confirm-danger-submit'); const $submit = $('.js-confirm-danger-submit', $modal);
$submit.disable(); $submit.disable();
$input.focus(); $input.focus();
$('.js-confirm-danger-input') $input.off('input').on('input', function handleInput() {
.off('input') const confirmText = rstrip($(this).val());
.on('input', function handleInput() { if (confirmText === confirmTextMatch) {
const confirmText = rstrip($(this).val()); $submit.enable();
if (confirmText === confirmTextMatch) { } else {
$submit.enable(); $submit.disable();
} else { }
$submit.disable(); });
} $('.js-confirm-danger-submit', $modal)
});
$('.js-confirm-danger-submit')
.off('click') .off('click')
.on('click', () => $form.submit()); .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() { export default function initConfirmDangerModal() {
$(document).on('click', '.js-confirm-danger', e => { $(document).on('click', '.js-confirm-danger', e => {
e.preventDefault();
const $btn = $(e.target); const $btn = $(e.target);
const $form = $btn.closest('form'); const checkFieldName = $btn.data('checkFieldName');
const text = $btn.data('confirmDangerMessage'); const checkFieldCompareValue = $btn.data('checkCompareValue');
openConfirmDangerModal($form, text); 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);
}
}); });
} }
...@@ -699,4 +699,8 @@ module ProjectsHelper ...@@ -699,4 +699,8 @@ module ProjectsHelper
def vue_file_list_enabled? def vue_file_list_enabled?
Feature.enabled?(:vue_file_list, @project) Feature.enabled?(:vue_file_list, @project)
end 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 end
- 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
...@@ -21,7 +21,9 @@ ...@@ -21,7 +21,9 @@
%input{ name: 'update_section', type: 'hidden', value: 'js-shared-permissions' } %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) %template.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data_json(@project)
.js-project-permissions-form .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)] } %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 .settings-header
......
---
title: Asks for confirmation before changing project visibility level
merge_request: 20170
author:
type: added
...@@ -77,6 +77,16 @@ by accident. The restricted visibility settings do not apply to admin users. ...@@ -77,6 +77,16 @@ by accident. The restricted visibility settings do not apply to admin users.
For details, see [Restricted visibility levels](../user/admin_area/settings/visibility_and_access_controls.md#restricted-visibility-levels). For details, see [Restricted visibility levels](../user/admin_area/settings/visibility_and_access_controls.md#restricted-visibility-levels).
## Reducing visibility
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/33358) in GitLab 12.6.
Reducing a project's visibility level will remove the fork relationship between the project and
any forked project. This is a potentially destructive action which requires confirmation before
this can be saved.
![Project visibility change confirmation](img/project_visibility_confirmation_v12_6.png)
<!-- ## Troubleshooting <!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues Include any troubleshooting steps that you can foresee. If you know beforehand what issues
......
...@@ -26,6 +26,10 @@ Set up your project's access, [visibility](../../../public_access/public_access. ...@@ -26,6 +26,10 @@ Set up your project's access, [visibility](../../../public_access/public_access.
![projects sharing permissions](img/sharing_and_permissions_settings_v12_3.png) ![projects sharing permissions](img/sharing_and_permissions_settings_v12_3.png)
CAUTION: **Caution:**
[Reducing a project's visibility level](../../../public_access/public_access.md#reducing-visibility)
will remove the fork relationship between the project and any forked project.
If Issues are disabled, or you can't access Issues because you're not a project member, then Labels and Milestones If Issues are disabled, or you can't access Issues because you're not a project member, then Labels and Milestones
links will be missing from the sidebar UI. links will be missing from the sidebar UI.
......
...@@ -11992,6 +11992,9 @@ msgstr "" ...@@ -11992,6 +11992,9 @@ msgstr ""
msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page." msgid "Once the exported file is ready, you will receive a notification email with a download link, or you can download it from this page."
msgstr "" msgstr ""
msgid "Once you confirm and press \"Reduce project visibility\":"
msgstr ""
msgid "One more item" msgid "One more item"
msgid_plural "%d more items" msgid_plural "%d more items"
msgstr[0] "" msgstr[0] ""
...@@ -14400,6 +14403,12 @@ msgstr "" ...@@ -14400,6 +14403,12 @@ msgstr ""
msgid "Redirect to SAML provider to test configuration" msgid "Redirect to SAML provider to test configuration"
msgstr "" msgstr ""
msgid "Reduce project visibility"
msgstr ""
msgid "Reduce this project’s visibility?"
msgstr ""
msgid "Reference:" msgid "Reference:"
msgstr "" msgstr ""
...@@ -20404,6 +20413,12 @@ msgstr "" ...@@ -20404,6 +20413,12 @@ msgstr ""
msgid "You'll need to use different branch names to get a valid comparison." msgid "You'll need to use different branch names to get a valid comparison."
msgstr "" msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end} in %{strong_start}%{group_name}%{strong_end}."
msgstr ""
msgid "You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}."
msgstr ""
msgid "You're not allowed to %{tag_start}edit%{tag_end} files in this project directly. Please fork this project, make your changes there, and submit a merge request." msgid "You're not allowed to %{tag_start}edit%{tag_end} files in this project directly. Please fork this project, make your changes there, and submit a merge request."
msgstr "" msgstr ""
......
# frozen_string_literal: true
require 'spec_helper'
describe 'User changes public project visibility', :js do
include ProjectForksHelper
before do
fork_project(project, project.owner)
sign_in(project.owner)
visit edit_project_path(project)
end
shared_examples 'changing visibility to private' do
it 'requires confirmation' do
visibility_select = first('.project-feature-controls .select-control')
visibility_select.select('Private')
page.within('#js-shared-permissions') do
click_button 'Save changes'
end
find('.js-confirm-danger-input').send_keys(project.path_with_namespace)
page.within '.modal' do
click_button 'Reduce project visibility'
end
expect(page).to have_text("Project '#{project.name}' was successfully updated")
end
end
context 'when a project is public' do
let(:project) { create(:project, :empty_repo, :public) }
it_behaves_like 'changing visibility to private'
end
context 'when the project is internal' do
let(:project) { create(:project, :empty_repo, :internal) }
it_behaves_like 'changing visibility to private'
end
end
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