Commit 2543ad9c authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch '232537-project-deletion-ui-text-clarity' into 'master'

Improve the project deletion UI text

See merge request gitlab-org/gitlab!79363
parents 8463d7ac 2ff35c24
<script> <script>
import { GlAlert, GlSprintf } from '@gitlab/ui';
import { __ } from '~/locale';
import SharedDeleteButton from './shared/delete_button.vue'; import SharedDeleteButton from './shared/delete_button.vue';
export default { export default {
components: { components: {
GlSprintf,
GlAlert,
SharedDeleteButton, SharedDeleteButton,
}, },
props: { props: {
...@@ -39,66 +35,17 @@ export default { ...@@ -39,66 +35,17 @@ export default {
required: true, required: true,
}, },
}, },
strings: {
alertTitle: __('You are about to permanently delete this project'),
alertBody: __(
'After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc.',
),
isNotForkMessage: __(
'This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:',
),
isForkMessage: __('This forked project has the following:'),
},
}; };
</script> </script>
<template> <template>
<shared-delete-button v-bind="{ confirmPhrase, formPath }"> <shared-delete-button
<template #modal-body> :confirm-phrase="confirmPhrase"
<gl-alert :form-path="formPath"
class="gl-mb-5" :is-fork="isFork"
variant="danger" :issues-count="issuesCount"
:title="$options.strings.alertTitle" :merge-requests-count="mergeRequestsCount"
:dismissible="false" :forks-count="forksCount"
> :stars-count="starsCount"
<p> />
<gl-sprintf v-if="isFork" :message="$options.strings.isForkMessage" />
<gl-sprintf v-else :message="$options.strings.isNotForkMessage">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</p>
<ul>
<li>
<gl-sprintf :message="n__('%d issue', '%d issues', issuesCount)">
<template #issuesCount>{{ issuesCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf
:message="n__('%d merge requests', '%d merge requests', mergeRequestsCount)"
>
<template #mergeRequestsCount>{{ mergeRequestsCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf :message="n__('%d fork', '%d forks', forksCount)">
<template #forksCount>{{ forksCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf :message="n__('%d star', '%d stars', starsCount)">
<template #starsCount>{{ starsCount }}</template>
</gl-sprintf>
</li>
</ul>
<gl-sprintf :message="$options.strings.alertBody">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</gl-alert>
</template>
</shared-delete-button>
</template> </template>
<script> <script>
import { GlModal, GlModalDirective, GlFormInput, GlButton } from '@gitlab/ui'; import { GlModal, GlModalDirective, GlFormInput, GlButton, GlAlert, GlSprintf } from '@gitlab/ui';
import { uniqueId } from 'lodash'; import { uniqueId } from 'lodash';
import csrf from '~/lib/utils/csrf'; import csrf from '~/lib/utils/csrf';
import { __ } from '~/locale'; import { __ } from '~/locale';
export default { export default {
components: { components: {
GlAlert,
GlModal, GlModal,
GlFormInput, GlFormInput,
GlButton, GlButton,
GlSprintf,
}, },
directives: { directives: {
GlModal: GlModalDirective, GlModal: GlModalDirective,
...@@ -22,6 +24,26 @@ export default { ...@@ -22,6 +24,26 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
isFork: {
type: Boolean,
required: true,
},
issuesCount: {
type: Number,
required: true,
},
mergeRequestsCount: {
type: Number,
required: true,
},
forksCount: {
type: Number,
required: true,
},
starsCount: {
type: Number,
required: true,
},
}, },
data() { data() {
return { return {
...@@ -55,8 +77,17 @@ export default { ...@@ -55,8 +77,17 @@ export default {
}, },
strings: { strings: {
deleteProject: __('Delete project'), deleteProject: __('Delete project'),
title: __('Delete project. Are you ABSOLUTELY SURE?'), title: __('Are you absolutely sure?'),
confirmText: __('Please type the following to confirm:'), confirmText: __('Enter the following to confirm:'),
isForkAlertTitle: __('You are about to delete this forked project containing:'),
isNotForkAlertTitle: __('You are about to delete this project containing:'),
isForkAlertBody: __('This process deletes the project repository and all related resources.'),
isNotForkAlertBody: __(
'This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources.',
),
isNotForkMessage: __(
'This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:',
),
}, },
}; };
</script> </script>
...@@ -83,7 +114,52 @@ export default { ...@@ -83,7 +114,52 @@ export default {
> >
<template #modal-title>{{ $options.strings.title }}</template> <template #modal-title>{{ $options.strings.title }}</template>
<div> <div>
<slot name="modal-body"></slot> <gl-alert class="gl-mb-5" variant="danger" :dismissible="false">
<h4 v-if="isFork" data-testid="delete-alert-title" class="gl-alert-title">
{{ $options.strings.isForkAlertTitle }}
</h4>
<h4 v-else data-testid="delete-alert-title" class="gl-alert-title">
{{ $options.strings.isNotForkAlertTitle }}
</h4>
<ul>
<li>
<gl-sprintf :message="n__('%d issue', '%d issues', issuesCount)">
<template #issuesCount>{{ issuesCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf
:message="n__('%d merge requests', '%d merge requests', mergeRequestsCount)"
>
<template #mergeRequestsCount>{{ mergeRequestsCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf :message="n__('%d fork', '%d forks', forksCount)">
<template #forksCount>{{ forksCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf :message="n__('%d star', '%d stars', starsCount)">
<template #starsCount>{{ starsCount }}</template>
</gl-sprintf>
</li>
</ul>
<gl-sprintf
v-if="isFork"
data-testid="delete-alert-body"
:message="$options.strings.isForkAlertBody"
/>
<gl-sprintf
v-else
data-testid="delete-alert-body"
:message="$options.strings.isNotForkAlertBody"
>
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</gl-alert>
<p class="gl-mb-1">{{ $options.strings.confirmText }}</p> <p class="gl-mb-1">{{ $options.strings.confirmText }}</p>
<p> <p>
<code class="gl-white-space-pre-wrap">{{ confirmPhrase }}</code> <code class="gl-white-space-pre-wrap">{{ confirmPhrase }}</code>
......
<script> <script>
import { GlAlert, GlLink, GlIcon, GlSprintf } from '@gitlab/ui'; import { GlLink, GlSprintf } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import SharedDeleteButton from '~/projects/components/shared/delete_button.vue'; import SharedDeleteButton from '~/projects/components/shared/delete_button.vue';
export default { export default {
components: { components: {
GlAlert,
GlSprintf, GlSprintf,
GlIcon,
GlLink, GlLink,
SharedDeleteButton, SharedDeleteButton,
}, },
...@@ -24,7 +22,7 @@ export default { ...@@ -24,7 +22,7 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
recoveryHelpPath: { restoreHelpPath: {
type: String, type: String,
required: true, required: true,
}, },
...@@ -49,84 +47,36 @@ export default { ...@@ -49,84 +47,36 @@ export default {
required: true, required: true,
}, },
}, },
strings: { strings: {
alertTitle: __('You are about to permanently delete this project'), restoreLabel: __('Restoring projects'),
alertBody: __( restoreMessage: __('This project can be restored until %{date}.'),
"After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests.",
),
helpLabel: __('Recovering projects'),
recoveryMessage: __('You can recover this project until %{date}'),
isNotForkMessage: __(
'This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:',
),
isForkMessage: __('This forked project has the following:'),
}, },
}; };
</script> </script>
<template> <template>
<shared-delete-button v-bind="{ confirmPhrase, formPath }"> <shared-delete-button
<template #modal-body> :confirm-phrase="confirmPhrase"
<gl-alert :form-path="formPath"
class="gl-mb-5" :is-fork="isFork"
variant="danger" :issues-count="issuesCount"
:title="$options.strings.alertTitle" :merge-requests-count="mergeRequestsCount"
:dismissible="false" :forks-count="forksCount"
> :stars-count="starsCount"
<p> >
<gl-sprintf v-if="isFork" :message="$options.strings.isForkMessage" />
<gl-sprintf v-else :message="$options.strings.isNotForkMessage">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</p>
<ul>
<li>
<gl-sprintf :message="n__('%d issue', '%d issues', issuesCount)">
<template #issuesCount>{{ issuesCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf
:message="n__('%d merge requests', '%d merge requests', mergeRequestsCount)"
>
<template #mergeRequestsCount>{{ mergeRequestsCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf :message="n__('%d fork', '%d forks', forksCount)">
<template #forksCount>{{ forksCount }}</template>
</gl-sprintf>
</li>
<li>
<gl-sprintf :message="n__('%d star', '%d stars', starsCount)">
<template #starsCount>{{ starsCount }}</template>
</gl-sprintf>
</li>
</ul>
<gl-sprintf :message="$options.strings.alertBody">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</gl-alert>
</template>
<template #modal-footer> <template #modal-footer>
<p <p
class="gl-display-flex gl-display-flex gl-align-items-center gl-mt-3 gl-mb-0 gl-text-gray-500" class="gl-display-flex gl-display-flex gl-align-items-center gl-mt-3 gl-mb-0 gl-text-gray-500"
> >
<gl-sprintf :message="$options.strings.recoveryMessage"> <gl-sprintf :message="$options.strings.restoreMessage">
<template #date> <template #date>{{ adjournedRemovalDate }}</template>
{{ adjournedRemovalDate }}
</template>
</gl-sprintf> </gl-sprintf>
<gl-link <gl-link
:aria-label="$options.strings.helpLabel" :aria-label="$options.strings.restoreLabel"
class="gl-display-flex gl-ml-2 gl-text-gray-500" class="gl-display-flex gl-ml-2"
:href="recoveryHelpPath" :href="restoreHelpPath"
> >{{ __('Learn More.') }}
<gl-icon name="question" />
</gl-link> </gl-link>
</p> </p>
</template> </template>
......
...@@ -11,7 +11,7 @@ export default (selector = '#js-project-adjourned-delete-button') => { ...@@ -11,7 +11,7 @@ export default (selector = '#js-project-adjourned-delete-button') => {
adjournedRemovalDate, adjournedRemovalDate,
confirmPhrase, confirmPhrase,
formPath, formPath,
recoveryHelpPath, restoreHelpPath,
isFork, isFork,
issuesCount, issuesCount,
mergeRequestsCount, mergeRequestsCount,
...@@ -28,7 +28,7 @@ export default (selector = '#js-project-adjourned-delete-button') => { ...@@ -28,7 +28,7 @@ export default (selector = '#js-project-adjourned-delete-button') => {
adjournedRemovalDate, adjournedRemovalDate,
confirmPhrase, confirmPhrase,
formPath, formPath,
recoveryHelpPath, restoreHelpPath,
isFork: parseBoolean(isFork), isFork: parseBoolean(isFork),
issuesCount: parseInt(issuesCount, 10), issuesCount: parseInt(issuesCount, 10),
mergeRequestsCount: parseInt(mergeRequestsCount, 10), mergeRequestsCount: parseInt(mergeRequestsCount, 10),
......
...@@ -103,13 +103,13 @@ module EE ...@@ -103,13 +103,13 @@ module EE
end end
def permanent_delete_message(project) def permanent_delete_message(project)
message = _('This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests.') message = _('This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}')
html_escape(message) % remove_message_data(project) html_escape(message) % remove_message_data(project)
end end
def marked_for_removal_message(project) def marked_for_removal_message(project)
date = permanent_deletion_date(Time.now.utc) date = permanent_deletion_date(Time.now.utc)
message = _('This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests.') message = _("This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains.")
html_escape(message) % remove_message_data(project).merge(date: date) html_escape(message) % remove_message_data(project).merge(date: date)
end end
...@@ -260,6 +260,7 @@ module EE ...@@ -260,6 +260,7 @@ module EE
def remove_message_data(project) def remove_message_data(project)
{ {
project_path_with_namespace: project.path_with_namespace,
project: project.path, project: project.path,
strongOpen: '<strong>'.html_safe, strongOpen: '<strong>'.html_safe,
strongClose: '</strong>'.html_safe, strongClose: '</strong>'.html_safe,
......
- return unless can?(current_user, :remove_project, project) - return unless can?(current_user, :remove_project, project)
- adjourned_deletion = project.adjourned_deletion? - adjourned_deletion = project.adjourned_deletion?
- adjourned_date = adjourned_deletion ? permanent_deletion_date(Time.now.utc).to_s : nil - adjourned_date = adjourned_deletion ? permanent_deletion_date(Time.now.utc).to_s : nil
- admin_help_path = help_page_path('user/admin_area/settings/visibility_and_access_controls', anchor: 'default-deletion-delay') - restore_help_path = help_page_path('user/project/settings/index', anchor: 'restore-a-project')
- recovery_help_path = help_page_path('user/project/settings/index', anchor: 'delete-a-project')
- merge_requests_count = Projects::AllMergeRequestsCountService.new(project).count - merge_requests_count = Projects::AllMergeRequestsCountService.new(project).count
- issues_count = Projects::AllIssuesCountService.new(project).count - issues_count = Projects::AllIssuesCountService.new(project).count
- forks_count = Projects::ForksCountService.new(project).count - forks_count = Projects::ForksCountService.new(project).count
- unless project.marked_for_deletion? - unless project.marked_for_deletion?
.sub-section .sub-section
%h4.danger-title= _('Delete project') %h4.danger-title= _('Delete this project')
%p
%strong= s_('Delayed Project Deletion (%{adjourned_deletion})') % { adjourned_deletion: adjourned_deletion ? 'Enabled' : 'Disabled' }
- if adjourned_deletion - if adjourned_deletion
= render 'projects/settings/marked_for_removal' = render 'projects/settings/marked_for_removal'
#js-project-adjourned-delete-button{ data: { recovery_help_path: recovery_help_path, adjourned_removal_date: adjourned_date, form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(forks_count), stars_count: number_with_delimiter(project.star_count) } } #js-project-adjourned-delete-button{ data: { restore_help_path: restore_help_path, adjourned_removal_date: adjourned_date, form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(forks_count), stars_count: number_with_delimiter(project.star_count) } }
- else - else
%p
%span.gl-text-gray-500= _('Projects will be permanently deleted immediately.')
= link_to(_('Customizable by an administrator.'), admin_help_path)
%p= permanent_delete_message(project) %p= permanent_delete_message(project)
%p
%strong= _('Are you ABSOLUTELY SURE you wish to delete this project?')
#js-project-delete-button{ data: { form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(forks_count), stars_count: number_with_delimiter(project.star_count) } } #js-project-delete-button{ data: { form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(forks_count), stars_count: number_with_delimiter(project.star_count) } }
- else - else
= render 'projects/settings/restore', project: project = render 'projects/settings/restore', project: project
......
- return unless @project.feature_available?(:adjourned_deletion_for_projects_and_groups) - return unless @project.feature_available?(:adjourned_deletion_for_projects_and_groups)
%p
%span.gl-text-gray-500= _('Projects will be permanently deleted after a %{waiting_period}-day waiting period.').html_safe % { waiting_period: ::Gitlab::CurrentSettings.deletion_adjourned_period }
= link_to(_('Customizable by an administrator.'), help_page_path('user/admin_area/settings/visibility_and_access_controls', anchor: 'default-deletion-delay'))
%p= marked_for_removal_message(@project) %p= marked_for_removal_message(@project)
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
- forks_count = Projects::ForksCountService.new(project).count - forks_count = Projects::ForksCountService.new(project).count
.sub-section .sub-section
%h4.danger-title= _('Permanently delete project') %h4.danger-title= _('Delete this project')
%p
%strong= _('Deleting the project will delete its repository and all related resources, including issues and merge requests.')
%p= permanent_delete_message(project) %p= permanent_delete_message(project)
%p
%strong= _('Are you ABSOLUTELY SURE you wish to delete this project?')
#js-project-delete-button{ data: { form_path: project_path(project, permanently_delete: true), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(forks_count), stars_count: number_with_delimiter(project.star_count) } } #js-project-delete-button{ data: { form_path: project_path(project, permanently_delete: true), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(forks_count), stars_count: number_with_delimiter(project.star_count) } }
...@@ -49,16 +49,17 @@ exports[`Project remove modal initialized matches the snapshot 1`] = ` ...@@ -49,16 +49,17 @@ exports[`Project remove modal initialized matches the snapshot 1`] = `
primarybuttontext="" primarybuttontext=""
secondarybuttonlink="" secondarybuttonlink=""
secondarybuttontext="" secondarybuttontext=""
title="You are about to permanently delete this project" title=""
variant="danger" variant="danger"
> >
<p> <h4
This project is class="gl-alert-title"
<strong> data-testid="delete-alert-title"
NOT >
</strong>
a fork, and has the following: You are about to delete this project containing:
</p>
</h4>
<ul> <ul>
<li> <li>
...@@ -77,21 +78,17 @@ exports[`Project remove modal initialized matches the snapshot 1`] = ` ...@@ -77,21 +78,17 @@ exports[`Project remove modal initialized matches the snapshot 1`] = `
4 stars 4 stars
</li> </li>
</ul> </ul>
After a project is permanently deleted, it This project is
<strong>
cannot be recovered
</strong>
. You will lose this project's repository and
<strong> <strong>
all related resources NOT
</strong> </strong>
, including issues and merge requests. a fork. This process deletes the project repository and all related resources.
</gl-alert-stub> </gl-alert-stub>
<p <p
class="gl-mb-1" class="gl-mb-1"
> >
Please type the following to confirm: Enter the following to confirm:
</p> </p>
<p> <p>
...@@ -111,18 +108,14 @@ exports[`Project remove modal initialized matches the snapshot 1`] = ` ...@@ -111,18 +108,14 @@ exports[`Project remove modal initialized matches the snapshot 1`] = `
<p <p
class="gl-display-flex gl-display-flex gl-align-items-center gl-mt-3 gl-mb-0 gl-text-gray-500" class="gl-display-flex gl-display-flex gl-align-items-center gl-mt-3 gl-mb-0 gl-text-gray-500"
> >
You can recover this project until This project can be restored until 2020-12-12.
2020-12-12
<gl-link-stub <gl-link-stub
aria-label="Recovering projects" aria-label="Restoring projects"
class="gl-display-flex gl-ml-2 gl-text-gray-500" class="gl-display-flex gl-ml-2"
href="recovery/help/path" href="recovery/help/path"
> >
<gl-icon-stub Learn More.
name="question"
size="16"
/>
</gl-link-stub> </gl-link-stub>
</p> </p>
</div> </div>
......
...@@ -14,7 +14,7 @@ describe('Project remove modal', () => { ...@@ -14,7 +14,7 @@ describe('Project remove modal', () => {
adjournedRemovalDate: '2020-12-12', adjournedRemovalDate: '2020-12-12',
confirmPhrase: 'foo', confirmPhrase: 'foo',
formPath: 'some/path', formPath: 'some/path',
recoveryHelpPath: 'recovery/help/path', restoreHelpPath: 'recovery/help/path',
isFork: false, isFork: false,
issuesCount: 1, issuesCount: 1,
mergeRequestsCount: 2, mergeRequestsCount: 2,
...@@ -52,7 +52,12 @@ describe('Project remove modal', () => { ...@@ -52,7 +52,12 @@ describe('Project remove modal', () => {
it('passes confirmPhrase and formPath props to the shared delete button', () => { it('passes confirmPhrase and formPath props to the shared delete button', () => {
expect(findSharedDeleteButton().props()).toEqual({ expect(findSharedDeleteButton().props()).toEqual({
confirmPhrase: defaultProps.confirmPhrase, confirmPhrase: defaultProps.confirmPhrase,
forksCount: defaultProps.forksCount,
formPath: defaultProps.formPath, formPath: defaultProps.formPath,
isFork: defaultProps.isFork,
issuesCount: defaultProps.issuesCount,
mergeRequestsCount: defaultProps.mergeRequestsCount,
starsCount: defaultProps.starsCount,
}); });
}); });
}); });
......
...@@ -327,6 +327,23 @@ RSpec.describe ProjectsHelper do ...@@ -327,6 +327,23 @@ RSpec.describe ProjectsHelper do
end end
end end
describe '#marked_for_removal_message' do
subject { helper.marked_for_removal_message(project) }
before do
allow(project).to receive(:adjourned_deletion?).and_return(enabled)
end
context 'when project has delayed deletion enabled' do
let(:enabled) { true }
specify do
deletion_date = helper.permanent_deletion_date(Time.now.utc)
expect(subject).to eq "This action deletes <code>#{project.path_with_namespace}</code> on #{deletion_date} and everything this project contains."
end
end
end
describe '#scheduled_for_deletion?' do describe '#scheduled_for_deletion?' do
context 'when project is NOT scheduled for deletion' do context 'when project is NOT scheduled for deletion' do
it { expect(helper.scheduled_for_deletion?(project)).to be false } it { expect(helper.scheduled_for_deletion?(project)).to be false }
......
...@@ -3099,12 +3099,6 @@ msgstr "" ...@@ -3099,12 +3099,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required" msgid "AdvancedSearch|Reindex required"
msgstr "" msgstr ""
msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
msgstr ""
msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
msgstr ""
msgid "After a successful password update you will be redirected to login screen." msgid "After a successful password update you will be redirected to login screen."
msgstr "" msgstr ""
...@@ -4657,10 +4651,10 @@ msgstr "" ...@@ -4657,10 +4651,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}" msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr "" msgstr ""
msgid "Are you ABSOLUTELY SURE you wish to delete this project?" msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr "" msgstr ""
msgid "Are you ABSOLUTELY SURE you wish to remove this group?" msgid "Are you absolutely sure?"
msgstr "" msgstr ""
msgid "Are you sure that you want to archive this project?" msgid "Are you sure that you want to archive this project?"
...@@ -10706,9 +10700,6 @@ msgstr "" ...@@ -10706,9 +10700,6 @@ msgstr ""
msgid "Customer relations" msgid "Customer relations"
msgstr "" msgstr ""
msgid "Customizable by an administrator."
msgstr ""
msgid "Customizable by owners." msgid "Customizable by owners."
msgstr "" msgstr ""
...@@ -11558,9 +11549,6 @@ msgstr "" ...@@ -11558,9 +11549,6 @@ msgstr ""
msgid "Definition" msgid "Definition"
msgstr "" msgstr ""
msgid "Delayed Project Deletion (%{adjourned_deletion})"
msgstr ""
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes." msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr "" msgstr ""
...@@ -11642,9 +11630,6 @@ msgstr "" ...@@ -11642,9 +11630,6 @@ msgstr ""
msgid "Delete project" msgid "Delete project"
msgstr "" msgstr ""
msgid "Delete project. Are you ABSOLUTELY SURE?"
msgstr ""
msgid "Delete row" msgid "Delete row"
msgstr "" msgstr ""
...@@ -11672,6 +11657,9 @@ msgstr "" ...@@ -11672,6 +11657,9 @@ msgstr ""
msgid "Delete this epic and all descendants?" msgid "Delete this epic and all descendants?"
msgstr "" msgstr ""
msgid "Delete this project"
msgstr ""
msgid "Delete user list" msgid "Delete user list"
msgstr "" msgstr ""
...@@ -13661,6 +13649,9 @@ msgstr "" ...@@ -13661,6 +13649,9 @@ msgstr ""
msgid "Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes." msgid "Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes."
msgstr "" msgstr ""
msgid "Enter the following to confirm:"
msgstr ""
msgid "Enter the name of your application, and we'll return a unique %{type}." msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr "" msgstr ""
...@@ -26229,9 +26220,6 @@ msgstr "" ...@@ -26229,9 +26220,6 @@ msgstr ""
msgid "Permalink" msgid "Permalink"
msgstr "" msgstr ""
msgid "Permanently delete project"
msgstr ""
msgid "Permanently remove group" msgid "Permanently remove group"
msgstr "" msgstr ""
...@@ -27123,9 +27111,6 @@ msgstr "" ...@@ -27123,9 +27111,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel." msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr "" msgstr ""
msgid "Please type the following to confirm:"
msgstr ""
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately." msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr "" msgstr ""
...@@ -28752,12 +28737,6 @@ msgstr "" ...@@ -28752,12 +28737,6 @@ msgstr ""
msgid "Projects to index" msgid "Projects to index"
msgstr "" msgstr ""
msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
msgstr ""
msgid "Projects will be permanently deleted immediately."
msgstr ""
msgid "Projects with critical vulnerabilities" msgid "Projects with critical vulnerabilities"
msgstr "" msgstr ""
...@@ -29718,9 +29697,6 @@ msgstr "" ...@@ -29718,9 +29697,6 @@ msgstr ""
msgid "Reconfigure" msgid "Reconfigure"
msgstr "" msgstr ""
msgid "Recovering projects"
msgstr ""
msgid "Recovery Codes" msgid "Recovery Codes"
msgstr "" msgstr ""
...@@ -30855,6 +30831,9 @@ msgstr "" ...@@ -30855,6 +30831,9 @@ msgstr ""
msgid "Restore project" msgid "Restore project"
msgstr "" msgstr ""
msgid "Restoring projects"
msgstr ""
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date." msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr "" msgstr ""
...@@ -36801,10 +36780,10 @@ msgstr "" ...@@ -36801,10 +36780,10 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key" msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr "" msgstr ""
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests." msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr "" msgstr ""
msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests." msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr "" msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}." msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
...@@ -36933,9 +36912,6 @@ msgstr "" ...@@ -36933,9 +36912,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly." msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr "" msgstr ""
msgid "This forked project has the following:"
msgstr ""
msgid "This form is disabled in preview" msgid "This form is disabled in preview"
msgstr "" msgstr ""
...@@ -37185,9 +37161,15 @@ msgstr "" ...@@ -37185,9 +37161,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule." msgid "This pipeline was triggered by a schedule."
msgstr "" msgstr ""
msgid "This process deletes the project repository and all related resources."
msgstr ""
msgid "This project" msgid "This project"
msgstr "" msgstr ""
msgid "This project can be restored until %{date}."
msgstr ""
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group." msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr "" msgstr ""
...@@ -37206,6 +37188,9 @@ msgstr "" ...@@ -37206,6 +37188,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:" msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr "" msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
msgstr ""
msgid "This project is archived and cannot be commented on." msgid "This project is archived and cannot be commented on."
msgstr "" msgstr ""
...@@ -41171,7 +41156,10 @@ msgstr "" ...@@ -41171,7 +41156,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification." msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr "" msgstr ""
msgid "You are about to permanently delete this project" msgid "You are about to delete this forked project containing:"
msgstr ""
msgid "You are about to delete this project containing:"
msgstr "" msgstr ""
msgid "You are about to transfer the control of your account to %{group_name} group. This action is NOT reversible, you won't be able to access any of your groups and projects outside of %{group_name} once this transfer is complete." msgid "You are about to transfer the control of your account to %{group_name} group. This action is NOT reversible, you won't be able to access any of your groups and projects outside of %{group_name} once this transfer is complete."
...@@ -41402,9 +41390,6 @@ msgstr "" ...@@ -41402,9 +41390,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design." msgid "You can only upload one design when dropping onto an existing design."
msgstr "" msgstr ""
msgid "You can recover this project until %{date}"
msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}" msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "" msgstr ""
......
...@@ -49,16 +49,17 @@ exports[`Project remove modal initialized matches the snapshot 1`] = ` ...@@ -49,16 +49,17 @@ exports[`Project remove modal initialized matches the snapshot 1`] = `
primarybuttontext="" primarybuttontext=""
secondarybuttonlink="" secondarybuttonlink=""
secondarybuttontext="" secondarybuttontext=""
title="You are about to permanently delete this project" title=""
variant="danger" variant="danger"
> >
<p> <h4
This project is class="gl-alert-title"
<strong> data-testid="delete-alert-title"
NOT >
</strong>
a fork, and has the following: You are about to delete this project containing:
</p>
</h4>
<ul> <ul>
<li> <li>
...@@ -77,25 +78,17 @@ exports[`Project remove modal initialized matches the snapshot 1`] = ` ...@@ -77,25 +78,17 @@ exports[`Project remove modal initialized matches the snapshot 1`] = `
4 stars 4 stars
</li> </li>
</ul> </ul>
After a project is permanently deleted, it This project is
<strong>
cannot be recovered
</strong>
. Permanently deleting this project will
<strong>
immediately delete
</strong>
its repositories and
<strong> <strong>
all related resources NOT
</strong> </strong>
, including issues, merge requests etc. a fork. This process deletes the project repository and all related resources.
</gl-alert-stub> </gl-alert-stub>
<p <p
class="gl-mb-1" class="gl-mb-1"
> >
Please type the following to confirm: Enter the following to confirm:
</p> </p>
<p> <p>
......
...@@ -50,7 +50,12 @@ describe('Project remove modal', () => { ...@@ -50,7 +50,12 @@ describe('Project remove modal', () => {
it('passes confirmPhrase and formPath props to the shared delete button', () => { it('passes confirmPhrase and formPath props to the shared delete button', () => {
expect(findSharedDeleteButton().props()).toEqual({ expect(findSharedDeleteButton().props()).toEqual({
confirmPhrase: defaultProps.confirmPhrase, confirmPhrase: defaultProps.confirmPhrase,
forksCount: defaultProps.forksCount,
formPath: defaultProps.formPath, formPath: defaultProps.formPath,
isFork: defaultProps.isFork,
issuesCount: defaultProps.issuesCount,
mergeRequestsCount: defaultProps.mergeRequestsCount,
starsCount: defaultProps.starsCount,
}); });
}); });
}); });
......
...@@ -34,13 +34,63 @@ exports[`Project remove modal intialized matches the snapshot 1`] = ` ...@@ -34,13 +34,63 @@ exports[`Project remove modal intialized matches the snapshot 1`] = `
ok-variant="danger" ok-variant="danger"
title-class="gl-text-red-500" title-class="gl-text-red-500"
> >
Delete project. Are you ABSOLUTELY SURE? Are you absolutely sure?
<div> <div>
<gl-alert-stub
class="gl-mb-5"
dismisslabel="Dismiss"
primarybuttonlink=""
primarybuttontext=""
secondarybuttonlink=""
secondarybuttontext=""
title=""
variant="danger"
>
<h4
class="gl-alert-title"
data-testid="delete-alert-title"
>
You are about to delete this project containing:
</h4>
<ul>
<li>
<gl-sprintf-stub
message="1 issue"
/>
</li>
<li>
<gl-sprintf-stub
message="2 merge requests"
/>
</li>
<li>
<gl-sprintf-stub
message="3 forks"
/>
</li>
<li>
<gl-sprintf-stub
message="4 stars"
/>
</li>
</ul>
<gl-sprintf-stub
data-testid="delete-alert-body"
message="This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
/>
</gl-alert-stub>
<p <p
class="gl-mb-1" class="gl-mb-1"
> >
Please type the following to confirm: Enter the following to confirm:
</p> </p>
<p> <p>
......
...@@ -12,15 +12,25 @@ describe('Project remove modal', () => { ...@@ -12,15 +12,25 @@ describe('Project remove modal', () => {
const findConfirmButton = () => wrapper.find('.js-modal-action-primary'); const findConfirmButton = () => wrapper.find('.js-modal-action-primary');
const findAuthenticityTokenInput = () => findFormElement().find('input[name=authenticity_token]'); const findAuthenticityTokenInput = () => findFormElement().find('input[name=authenticity_token]');
const findModal = () => wrapper.find(GlModal); const findModal = () => wrapper.find(GlModal);
const findTitle = () => wrapper.find('[data-testid="delete-alert-title"]');
const findAlertBody = () => wrapper.find('[data-testid="delete-alert-body"]');
const defaultProps = { const defaultProps = {
confirmPhrase: 'foo', confirmPhrase: 'foo',
formPath: 'some/path', formPath: 'some/path',
isFork: false,
issuesCount: 1,
mergeRequestsCount: 2,
forksCount: 3,
starsCount: 4,
}; };
const createComponent = (data = {}, stubs = {}) => { const createComponent = (data = {}, stubs = {}, props = {}) => {
wrapper = shallowMount(SharedDeleteButton, { wrapper = shallowMount(SharedDeleteButton, {
propsData: defaultProps, propsData: {
...defaultProps,
...props,
},
data: () => data, data: () => data,
stubs: { stubs: {
GlModal: stubComponent(GlModal, { GlModal: stubComponent(GlModal, {
...@@ -88,4 +98,20 @@ describe('Project remove modal', () => { ...@@ -88,4 +98,20 @@ describe('Project remove modal', () => {
expect(findFormElement().element.submit).toHaveBeenCalled(); expect(findFormElement().element.submit).toHaveBeenCalled();
}); });
}); });
describe('when project is a fork', () => {
beforeEach(() => {
createComponent({}, {}, { isFork: true });
});
it('matches the fork title', () => {
expect(findTitle().text()).toEqual('You are about to delete this forked project containing:');
});
it('matches the fork body', () => {
expect(findAlertBody().attributes().message).toEqual(
'This process deletes the project repository and all related resources.',
);
});
});
}); });
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