Commit d027add4 authored by Vitaly Slobodin's avatar Vitaly Slobodin

Merge branch 'ek-replace-visibility-danger-modal' into 'master'

Migrate reduce visibility confirmation modal to gl-modal

See merge request gitlab-org/gitlab!76417
parents c5d2724a b18f0092
import Vue from 'vue'; import Vue from 'vue';
import { pickBy } from 'lodash';
import { parseBoolean } from './lib/utils/common_utils'; import { parseBoolean } from './lib/utils/common_utils';
import ConfirmDanger from './vue_shared/components/confirm_danger/confirm_danger.vue'; import ConfirmDanger from './vue_shared/components/confirm_danger/confirm_danger.vue';
...@@ -12,21 +13,32 @@ export default () => { ...@@ -12,21 +13,32 @@ export default () => {
buttonText, buttonText,
buttonClass = '', buttonClass = '',
buttonTestid = null, buttonTestid = null,
buttonVariant = null,
confirmDangerMessage, confirmDangerMessage,
confirmButtonText = null,
disabled = false, disabled = false,
additionalInformation,
htmlConfirmationMessage,
} = el.dataset; } = el.dataset;
return new Vue({ return new Vue({
el, el,
provide: { provide: pickBy(
{
htmlConfirmationMessage,
confirmDangerMessage, confirmDangerMessage,
additionalInformation,
confirmButtonText,
}, },
(v) => Boolean(v),
),
render: (createElement) => render: (createElement) =>
createElement(ConfirmDanger, { createElement(ConfirmDanger, {
props: { props: {
phrase, phrase,
buttonText, buttonText,
buttonClass, buttonClass,
buttonVariant,
buttonTestid, buttonTestid,
disabled: parseBoolean(disabled), disabled: parseBoolean(disabled),
}, },
......
...@@ -36,6 +36,11 @@ export default { ...@@ -36,6 +36,11 @@ export default {
required: false, required: false,
default: 'confirm-danger-button', default: 'confirm-danger-button',
}, },
buttonVariant: {
type: String,
required: false,
default: 'danger',
},
}, },
modalId: CONFIRM_DANGER_MODAL_ID, modalId: CONFIRM_DANGER_MODAL_ID,
}; };
...@@ -45,7 +50,7 @@ export default { ...@@ -45,7 +50,7 @@ export default {
<gl-button <gl-button
v-gl-modal="$options.modalId" v-gl-modal="$options.modalId"
:class="buttonClass" :class="buttonClass"
variant="danger" :variant="buttonVariant"
:disabled="disabled" :disabled="disabled"
:data-testid="buttonTestid" :data-testid="buttonTestid"
>{{ buttonText }}</gl-button >{{ buttonText }}</gl-button
......
...@@ -11,7 +11,9 @@ const Template = (args, { argTypes }) => ({ ...@@ -11,7 +11,9 @@ const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes), props: Object.keys(argTypes),
template: '<confirm-danger v-bind="$props" />', template: '<confirm-danger v-bind="$props" />',
provide: { provide: {
confirmDangerMessage: 'You require more Vespene Gas', additionalInformation: args.additionalInformation || null,
confirmDangerMessage: args.confirmDangerMessage || 'You require more Vespene Gas',
htmlConfirmationMessage: args.confirmDangerMessage || false,
}, },
}); });
...@@ -26,3 +28,16 @@ Disabled.args = { ...@@ -26,3 +28,16 @@ Disabled.args = {
...Default.args, ...Default.args,
disabled: true, disabled: true,
}; };
export const AdditionalInformation = Template.bind({});
AdditionalInformation.args = {
...Default.args,
additionalInformation: 'This replaces the default warning information',
};
export const HtmlMessage = Template.bind({});
HtmlMessage.args = {
...Default.args,
confirmDangerMessage: 'You strongly require more <strong>Vespene Gas</strong>',
htmlConfirmationMessage: true,
};
<script> <script>
import { GlAlert, GlModal, GlFormGroup, GlFormInput, GlSprintf } from '@gitlab/ui'; import {
GlAlert,
GlModal,
GlFormGroup,
GlFormInput,
GlSafeHtmlDirective as SafeHtml,
GlSprintf,
} from '@gitlab/ui';
import { import {
CONFIRM_DANGER_MODAL_BUTTON, CONFIRM_DANGER_MODAL_BUTTON,
CONFIRM_DANGER_MODAL_TITLE, CONFIRM_DANGER_MODAL_TITLE,
...@@ -17,13 +24,22 @@ export default { ...@@ -17,13 +24,22 @@ export default {
GlFormInput, GlFormInput,
GlSprintf, GlSprintf,
}, },
directives: {
SafeHtml,
},
inject: { inject: {
htmlConfirmationMessage: {
default: false,
},
confirmDangerMessage: { confirmDangerMessage: {
default: '', default: '',
}, },
confirmButtonText: { confirmButtonText: {
default: CONFIRM_DANGER_MODAL_BUTTON, default: CONFIRM_DANGER_MODAL_BUTTON,
}, },
additionalInformation: {
default: CONFIRM_DANGER_WARNING,
},
}, },
props: { props: {
modalId: { modalId: {
...@@ -81,9 +97,12 @@ export default { ...@@ -81,9 +97,12 @@ export default {
:dismissible="false" :dismissible="false"
class="gl-mb-4" class="gl-mb-4"
> >
<span v-if="htmlConfirmationMessage" v-safe-html="confirmDangerMessage"></span>
<span v-else>
{{ confirmDangerMessage }} {{ confirmDangerMessage }}
</span>
</gl-alert> </gl-alert>
<p data-testid="confirm-danger-warning">{{ $options.i18n.CONFIRM_DANGER_WARNING }}</p> <p data-testid="confirm-danger-warning">{{ additionalInformation }}</p>
<p data-testid="confirm-danger-phrase"> <p data-testid="confirm-danger-phrase">
<gl-sprintf :message="$options.i18n.CONFIRM_DANGER_PHRASE_TEXT"> <gl-sprintf :message="$options.i18n.CONFIRM_DANGER_PHRASE_TEXT">
<template #phrase_code> <template #phrase_code>
......
...@@ -660,6 +660,33 @@ module ProjectsHelper ...@@ -660,6 +660,33 @@ module ProjectsHelper
project.unlink_forks_upon_visibility_decrease_enabled? && project.visibility_level > Gitlab::VisibilityLevel::PRIVATE && project.forks_count > 0 project.unlink_forks_upon_visibility_decrease_enabled? && project.visibility_level > Gitlab::VisibilityLevel::PRIVATE && project.forks_count > 0
end end
def confirm_reduce_visibility_message(project)
strong_start = "<strong>".html_safe
strong_end = "</strong>".html_safe
message = _("You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}.")
if project.group
message = _("You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end} in %{strong_start}%{group_name}%{strong_end}.")
end
html_escape(message) % { strong_start: strong_start, strong_end: strong_end, project_name: project.name, group_name: project.group ? project.group.name : nil }
end
def visibility_confirm_modal_data(project, remove_form_id = nil)
{
remove_form_id: remove_form_id,
qa_selector: 'visibility_features_permissions_save_button',
button_text: _('Save changes'),
button_testid: 'reduce-project-visibility-button',
button_variant: 'confirm',
confirm_button_text: _('Reduce project visibility'),
confirm_danger_message: confirm_reduce_visibility_message(project),
phrase: project.full_path,
additional_information: _('Note: current forks will keep their visibility level.'),
html_confirmation_message: true
}
end
def build_project_breadcrumb_link(project) def build_project_breadcrumb_link(project)
project_name = simple_sanitize(project.name) project_name = simple_sanitize(project.name)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
- page_title _("General") - page_title _("General")
- @content_class = "limit-container-width" unless fluid_layout - @content_class = "limit-container-width" unless fluid_layout
- expanded = expanded_by_default? - expanded = expanded_by_default?
- remove_visibility_form_id = 'reduce-visibility-form'
%section.settings.general-settings.no-animate.expanded#js-general-settings %section.settings.general-settings.no-animate.expanded#js-general-settings
.settings-header .settings-header
...@@ -17,13 +18,11 @@ ...@@ -17,13 +18,11 @@
%p= _('Choose visibility level, enable/disable project features and their permissions, disable email notifications, and show default award emoji.') %p= _('Choose visibility level, enable/disable project features and their permissions, disable email notifications, and show default award emoji.')
.settings-content .settings-content
= form_for @project, html: { multipart: true, class: "sharing-permissions-form" }, authenticity_token: true do |f| = form_for @project, html: { multipart: true, class: "sharing-permissions-form", id: remove_visibility_form_id }, authenticity_token: true do |f|
%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(@project).to_json.html_safe %template.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data(@project).to_json.html_safe
.js-project-permissions-form .js-project-permissions-form
- if show_visibility_confirm_modal?(@project) = f.submit _('Save changes'), class: "btn gl-button btn-confirm #{('js-confirm-danger' if show_visibility_confirm_modal?(@project))}", data: visibility_confirm_modal_data(@project, remove_visibility_form_id)
= render "visibility_modal"
= f.submit _('Save changes'), class: "btn gl-button btn-confirm #{('js-legacy-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.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)], data: { qa_selector: 'merge_request_settings_content' } } %section.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)], data: { qa_selector: 'merge_request_settings_content' } }
.settings-header .settings-header
......
...@@ -24088,6 +24088,9 @@ msgstr "" ...@@ -24088,6 +24088,9 @@ msgstr ""
msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token." msgid "Note: Consider asking your GitLab administrator to configure %{github_integration_link}, which will allow login via GitHub and allow importing repositories without generating a Personal Access Token."
msgstr "" msgstr ""
msgid "Note: current forks will keep their visibility level."
msgstr ""
msgid "NoteForm|Note" msgid "NoteForm|Note"
msgstr "" msgstr ""
......
...@@ -5,9 +5,7 @@ module QA ...@@ -5,9 +5,7 @@ module QA
module Project module Project
module Settings module Settings
class VisibilityFeaturesPermissions < Page::Base class VisibilityFeaturesPermissions < Page::Base
include QA::Page::Component::Select2 view 'app/helpers/projects_helper.rb' do
view 'app/views/projects/edit.html.haml' do
element :visibility_features_permissions_save_button element :visibility_features_permissions_save_button
end end
......
...@@ -22,7 +22,7 @@ RSpec.describe 'User changes public project visibility', :js do ...@@ -22,7 +22,7 @@ RSpec.describe 'User changes public project visibility', :js do
click_button 'Save changes' click_button 'Save changes'
end end
find('.js-legacy-confirm-danger-input').send_keys(project.path_with_namespace) fill_in 'confirm_name_input', with: project.path_with_namespace
page.within '.modal' do page.within '.modal' do
click_button 'Reduce project visibility' click_button 'Reduce project visibility'
......
...@@ -10,6 +10,7 @@ describe('Confirm Danger Modal', () => { ...@@ -10,6 +10,7 @@ describe('Confirm Danger Modal', () => {
const phrase = 'En Taro Adun'; const phrase = 'En Taro Adun';
const buttonText = 'Click me!'; const buttonText = 'Click me!';
const buttonClass = 'gl-w-full'; const buttonClass = 'gl-w-full';
const buttonVariant = 'info';
const modalId = CONFIRM_DANGER_MODAL_ID; const modalId = CONFIRM_DANGER_MODAL_ID;
const findBtn = () => wrapper.findComponent(GlButton); const findBtn = () => wrapper.findComponent(GlButton);
...@@ -21,6 +22,7 @@ describe('Confirm Danger Modal', () => { ...@@ -21,6 +22,7 @@ describe('Confirm Danger Modal', () => {
propsData: { propsData: {
buttonText, buttonText,
buttonClass, buttonClass,
buttonVariant,
phrase, phrase,
...props, ...props,
}, },
...@@ -57,6 +59,10 @@ describe('Confirm Danger Modal', () => { ...@@ -57,6 +59,10 @@ describe('Confirm Danger Modal', () => {
expect(findBtn().classes()).toContain(buttonClass); expect(findBtn().classes()).toContain(buttonClass);
}); });
it('passes `buttonVariant` prop to button', () => {
expect(findBtn().attributes('variant')).toBe(buttonVariant);
});
it('will emit `confirm` when the modal confirms', () => { it('will emit `confirm` when the modal confirms', () => {
expect(wrapper.emitted('confirm')).toBeUndefined(); expect(wrapper.emitted('confirm')).toBeUndefined();
......
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