Module: Namespaces::DeletableHelper

Includes:
NamespaceHelper
Included in:
Emails::Groups, Emails::Projects, GroupChildEntity, Types::GroupType, Types::ProjectType
Defined in:
app/helpers/namespaces/deletable_helper.rb

Instance Method Summary collapse

Instance Method Details

#_additional_removed_items(group) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'app/helpers/namespaces/deletable_helper.rb', line 200

def _additional_removed_items(group)
  relations = {
    ->(count) { n_('%{count} subgroup', '%{count} subgroups', count) } => group.children,
    ->(count) {
      n_('%{count} active project', '%{count} active projects', count)
    } => group.all_projects.non_archived,
    ->(count) {
      n_('%{count} archived project', '%{count} archived projects', count)
    } => group.all_projects.archived
  }

  counts = relations.filter_map do |i18n_proc, relation|
    count = limited_counter_with_delimiter(relation, limit: 100, include_zero: false)
    next unless count

    (:li, format(i18n_proc[count.to_i], count: count))
  end

  if counts.any?
    safe_join([
      (:span, _(" This action will also delete:")),
      (:ul, safe_join(counts))
    ])
  else
    ''
  end
end

#_deletion_scheduled_in_hierarchy_chain_message(namespace) ⇒ Object



41
42
43
44
45
46
47
# File 'app/helpers/namespaces/deletable_helper.rb', line 41

def _deletion_scheduled_in_hierarchy_chain_message(namespace)
  if namespace.self_deletion_scheduled?
    _self_deletion_scheduled_message(namespace)
  else
    _parent_deletion_scheduled_message(namespace)
  end
end

#_parent_deletion_scheduled_message(namespace) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/helpers/namespaces/deletable_helper.rb', line 64

def _parent_deletion_scheduled_message(namespace)
  namespace_pending_deletion = namespace.first_scheduled_for_deletion_in_hierarchy_chain
  date = permanent_deletion_date_formatted(namespace_pending_deletion)

  messages = {
    group: _('This group will be deleted on %{date} because its parent group is ' \
      'scheduled for deletion.'),
    project: _('This project will be deleted on %{date} because its parent group is ' \
      'scheduled for deletion.')
  }

  safe_format(
    message_for_namespace(namespace, messages),
    date: tag.strong(date)
  )
end

#_permanently_delete_group_message(group) ⇒ Object



192
193
194
195
196
197
198
# File 'app/helpers/namespaces/deletable_helper.rb', line 192

def _permanently_delete_group_message(group)
  content = ''.html_safe
  content << (:span,
    format(_("You are about to delete the group %{group_name}."), group_name: group.name))
  content << _additional_removed_items(group)
  content << _remove_group_warning
end

#_project_delete_button_shared_data(project, button_text = nil) ⇒ Object



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'app/helpers/namespaces/deletable_helper.rb', line 238

def _project_delete_button_shared_data(project, button_text = nil)
  merge_requests_count = ::Projects::AllMergeRequestsCountService.new(project).count
  issues_count = ::Projects::AllIssuesCountService.new(project).count
  forks_count = ::Projects::ForksCountService.new(project).count

  {
    confirm_phrase: delete_confirm_phrase(project),
    name_with_namespace: project.name_with_namespace,
    is_fork: project.forked? ? 'true' : 'false',
    issues_count: issues_count,
    merge_requests_count: merge_requests_count,
    forks_count: forks_count,
    stars_count: project.star_count,
    button_text: button_text.presence || _('Delete'),
    permanent_deletion_date: permanent_deletion_date_formatted,
    marked_for_deletion: project.scheduled_for_deletion_in_hierarchy_chain?.to_s
  }
end

#_remove_group_warningObject



228
229
230
231
232
233
234
235
236
# File 'app/helpers/namespaces/deletable_helper.rb', line 228

def _remove_group_warning
  (:p, class: 'gl-mb-0') do
    safe_format(
      _('After you delete a group, you %{strongOpen}cannot%{strongClose} restore it or its components.'),
      strongOpen: '<strong>'.html_safe,
      strongClose: '</strong>'.html_safe
    )
  end
end

#_self_deletion_in_progress_message(namespace) ⇒ Object



30
31
32
33
34
35
36
37
38
39
# File 'app/helpers/namespaces/deletable_helper.rb', line 30

def _self_deletion_in_progress_message(namespace)
  return unless namespace.self_deletion_in_progress?

  messages = {
    group: _('This group and its subgroups are being deleted.'),
    project: _('This project is being deleted. Repository and other project resources are read-only.')
  }

  message_for_namespace(namespace, messages)
end

#_self_deletion_scheduled_message(namespace) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'app/helpers/namespaces/deletable_helper.rb', line 49

def _self_deletion_scheduled_message(namespace)
  date = permanent_deletion_date_formatted(namespace)

  messages = {
    group: _('This group and its subgroups and projects are pending deletion, and will be deleted on %{date}.'),
    project: _('This project is pending deletion, and will be deleted on %{date}. Repository and other project ' \
      'resources are read-only.')
  }

  safe_format(
    message_for_namespace(namespace, messages),
    date: tag.strong(date)
  )
end

#confirm_remove_group_message(group, permanently_remove) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
# File 'app/helpers/namespaces/deletable_helper.rb', line 141

def confirm_remove_group_message(group, permanently_remove)
  return _permanently_delete_group_message(group) if permanently_remove || group.self_deletion_scheduled?

  safe_format(
    _("This group and its contents, including subgroups and projects, will be permanently deleted on %{date}. " \
      "After this point, your data cannot be recovered. " \
      "Scheduled pipelines will not run during deletion."),
    deletion_adjourned_period: group.deletion_adjourned_period,
    date: tag.strong(permanent_deletion_date_formatted)
  )
end

#delete_delayed_namespace_message(namespace) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/helpers/namespaces/deletable_helper.rb', line 81

def delete_delayed_namespace_message(namespace)
  messages = {
    group: _('This action will permanently delete this group, including its subgroups and projects, ' \
      'on %{date}. Scheduled pipelines will not run during deletion.'),
    project: _('This action will permanently delete this project, including all its resources, ' \
      'on %{date}. Scheduled pipelines will not run during deletion.')
  }

  safe_format(
    message_for_namespace(namespace, messages),
    deletion_adjourned_period: namespace.deletion_adjourned_period,
    date: tag.strong(permanent_deletion_date_formatted)
  )
end

#delete_immediately_namespace_scheduled_for_deletion_message(namespace) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'app/helpers/namespaces/deletable_helper.rb', line 96

def delete_immediately_namespace_scheduled_for_deletion_message(namespace)
  messages = {
    group: _('This group is scheduled for deletion on %{date}. ' \
      'This action will permanently delete this group, ' \
      'including its subgroups and projects, %{strongOpen}immediately%{strongClose}. ' \
      'This action cannot be undone.'),
    project: _('This project is scheduled for deletion on %{date}. ' \
      'This action will permanently delete this project, ' \
      'including all its resources, %{strongOpen}immediately%{strongClose}. ' \
      'This action cannot be undone.')
  }

  safe_format(
    message_for_namespace(namespace, messages),
    date: tag.strong(permanent_deletion_date_formatted(namespace)),
    strongOpen: '<strong>'.html_safe,
    strongClose: '</strong>'.html_safe
  )
end

#deletion_in_progress_or_scheduled_in_hierarchy_chain?(namespace) ⇒ Boolean

Returns:



20
21
22
23
24
# File 'app/helpers/namespaces/deletable_helper.rb', line 20

def deletion_in_progress_or_scheduled_in_hierarchy_chain?(namespace)
  return false unless namespace.respond_to?(:deletion_in_progress_or_scheduled_in_hierarchy_chain?)

  namespace.deletion_in_progress_or_scheduled_in_hierarchy_chain?
end

#group_confirm_modal_data(group:, remove_form_id: nil, permanently_remove: false, button_text: nil, has_security_policy_project: false) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'app/helpers/namespaces/deletable_helper.rb', line 116

def group_confirm_modal_data(
  group:,
  remove_form_id: nil,
  permanently_remove: false,
  button_text: nil,
  has_security_policy_project: false
)
  {
    remove_form_id: remove_form_id,
    button_text: button_text.nil? ? _('Delete') : button_text,
    button_testid: 'remove-group-button',
    disabled: (group.linked_to_subscription? || has_security_policy_project).to_s,
    confirm_danger_message: confirm_remove_group_message(group, permanently_remove),
    phrase: group.full_path,
    html_confirmation_message: 'true',
    form_path: group_path(group),
    confirm_phrase: group.full_path,
    full_name: group.full_name,
    subgroups_count: group.subgroup_count,
    projects_count: group.project_count,
    marked_for_deletion: group.scheduled_for_deletion_in_hierarchy_chain?.to_s,
    permanent_deletion_date: permanent_deletion_date_formatted
  }
end

#permanent_deletion_date_formatted(container_or_date = Date.current, format: '%F') ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
# File 'app/helpers/namespaces/deletable_helper.rb', line 7

def permanent_deletion_date_formatted(container_or_date = Date.current, format: '%F')
  date =
    if container_or_date.respond_to?(:self_deletion_scheduled_deletion_created_on)
      container_or_date.self_deletion_scheduled_deletion_created_on
    else
      container_or_date
    end

  return unless date.is_a?(Date) || date.is_a?(Time)

  ::Gitlab::CurrentSettings.deletion_adjourned_period.days.since(date).strftime(format)
end

#project_delete_delayed_button_data(project) ⇒ Object



153
154
155
156
157
# File 'app/helpers/namespaces/deletable_helper.rb', line 153

def project_delete_delayed_button_data(project)
  _project_delete_button_shared_data(project).merge({
    form_path: project_path(project)
  })
end

#project_delete_immediately_button_data(project) ⇒ Object



159
160
161
162
163
# File 'app/helpers/namespaces/deletable_helper.rb', line 159

def project_delete_immediately_button_data(project)
  _project_delete_button_shared_data(project, s_('ProjectSettings|Delete immediately')).merge({
    form_path: project_path(project, permanently_delete: true)
  })
end

#restore_namespace_path(namespace) ⇒ Object



174
175
176
177
178
179
180
181
# File 'app/helpers/namespaces/deletable_helper.rb', line 174

def restore_namespace_path(namespace)
  paths = {
    group: ->(namespace) { group_restore_path(namespace) },
    project: ->(namespace) { namespace_project_restore_path(namespace.parent, namespace) }
  }

  message_for_namespace(namespace, paths)[namespace]
end

#restore_namespace_scheduled_for_deletion_message(namespace) ⇒ Object



183
184
185
186
187
188
189
190
# File 'app/helpers/namespaces/deletable_helper.rb', line 183

def restore_namespace_scheduled_for_deletion_message(namespace)
  messages = {
    group: _("This group will be restored from scheduled deletion."),
    project: _("This project will be restored from scheduled deletion.")
  }

  message_for_namespace(namespace, messages)
end

#restore_namespace_title(namespace) ⇒ Object



165
166
167
168
169
170
171
172
# File 'app/helpers/namespaces/deletable_helper.rb', line 165

def restore_namespace_title(namespace)
  messages = {
    group: _('Restore group'),
    project: _('Restore project')
  }

  message_for_namespace(namespace, messages)
end

#self_or_ancestors_deletion_in_progress_or_scheduled_message(namespace) ⇒ Object



26
27
28
# File 'app/helpers/namespaces/deletable_helper.rb', line 26

def self_or_ancestors_deletion_in_progress_or_scheduled_message(namespace)
  _self_deletion_in_progress_message(namespace) || _deletion_scheduled_in_hierarchy_chain_message(namespace)
end