diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-17 11:59:07 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-17 11:59:07 +0000 |
commit | 8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca (patch) | |
tree | 544930fb309b30317ae9797a9683768705d664c4 /app/services/issues | |
parent | 4b1de649d0168371549608993deac953eb692019 (diff) | |
download | gitlab-ce-8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca.tar.gz |
Add latest changes from gitlab-org/gitlab@13-7-stable-eev13.7.0-rc42
Diffstat (limited to 'app/services/issues')
-rw-r--r-- | app/services/issues/base_service.rb | 16 | ||||
-rw-r--r-- | app/services/issues/clone_service.rb | 90 | ||||
-rw-r--r-- | app/services/issues/create_service.rb | 16 | ||||
-rw-r--r-- | app/services/issues/export_csv_service.rb | 2 | ||||
-rw-r--r-- | app/services/issues/update_service.rb | 15 |
5 files changed, 120 insertions, 19 deletions
diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb index 978ea6fe9bc..25f319da03b 100644 --- a/app/services/issues/base_service.rb +++ b/app/services/issues/base_service.rb @@ -73,22 +73,6 @@ module Issues Milestones::IssuesCountService.new(milestone).delete_cache end - - # Applies label "incident" (creates it if missing) to incident issues. - # Please use in "after" hooks only to ensure we are not appyling - # labels prematurely. - def add_incident_label(issue) - return unless issue.incident? - - label = ::IncidentManagement::CreateIncidentLabelService - .new(project, current_user) - .execute - .payload[:label] - - return if issue.label_ids.include?(label.id) - - issue.labels << label - end end end diff --git a/app/services/issues/clone_service.rb b/app/services/issues/clone_service.rb new file mode 100644 index 00000000000..789da312958 --- /dev/null +++ b/app/services/issues/clone_service.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +module Issues + class CloneService < Issuable::Clone::BaseService + CloneError = Class.new(StandardError) + + def execute(issue, target_project, with_notes: false) + @target_project = target_project + @with_notes = with_notes + + unless issue.can_clone?(current_user, target_project) + raise CloneError, s_('CloneIssue|Cannot clone issue due to insufficient permissions!') + end + + if target_project.pending_delete? + raise CloneError, s_('CloneIssue|Cannot clone issue to target project as it is pending deletion.') + end + + super(issue, target_project) + + notify_participants + + queue_copy_designs + + new_entity + end + + private + + attr_reader :target_project + attr_reader :with_notes + + def update_new_entity + # we don't call `super` because we want to be able to decide whether or not to copy all comments over. + update_new_entity_description + update_new_entity_attributes + copy_award_emoji + copy_notes if with_notes + end + + def update_old_entity + # no-op + # The base_service closes the old issue, we don't want that, so we override here so nothing happens. + end + + def create_new_entity + new_params = { + id: nil, + iid: nil, + project: target_project, + author: current_user, + assignee_ids: original_entity.assignee_ids + } + + new_params = original_entity.serializable_hash.symbolize_keys.merge(new_params) + + # Skip creation of system notes for existing attributes of the issue. The system notes of the old + # issue are copied over so we don't want to end up with duplicate notes. + CreateService.new(target_project, current_user, new_params).execute(skip_system_notes: true) + end + + def queue_copy_designs + return unless original_entity.designs.present? + + response = DesignManagement::CopyDesignCollection::QueueService.new( + current_user, + original_entity, + new_entity + ).execute + + log_error(response.message) if response.error? + end + + def notify_participants + notification_service.async.issue_cloned(original_entity, new_entity, current_user) + end + + def add_note_from + SystemNoteService.noteable_cloned(new_entity, target_project, + original_entity, current_user, + direction: :from) + end + + def add_note_to + SystemNoteService.noteable_cloned(original_entity, old_project, + new_entity, current_user, + direction: :to) + end + end +end diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb index fb7683f940d..44de8eb6389 100644 --- a/app/services/issues/create_service.rb +++ b/app/services/issues/create_service.rb @@ -49,6 +49,22 @@ module Issues def user_agent_detail_service UserAgentDetailService.new(@issue, @request) end + + # Applies label "incident" (creates it if missing) to incident issues. + # For use in "after" hooks only to ensure we are not appyling + # labels prematurely. + def add_incident_label(issue) + return unless issue.incident? + + label = ::IncidentManagement::CreateIncidentLabelService + .new(project, current_user) + .execute + .payload[:label] + + return if issue.label_ids.include?(label.id) + + issue.labels << label + end end end diff --git a/app/services/issues/export_csv_service.rb b/app/services/issues/export_csv_service.rb index 1dcdfb9faea..8f513632929 100644 --- a/app/services/issues/export_csv_service.rb +++ b/app/services/issues/export_csv_service.rb @@ -34,7 +34,7 @@ module Issues private def associations_to_preload - %i(author assignees timelogs) + %i(author assignees timelogs milestone) end def header_to_value_hash diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index b9832400302..127ed04cf51 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -9,7 +9,7 @@ module Issues handle_move_between_ids(issue) filter_spam_check_params change_issue_duplicate(issue) - move_issue_to_new_project(issue) || update_task_event(issue) || update(issue) + move_issue_to_new_project(issue) || clone_issue(issue) || update_task_event(issue) || update(issue) end def update(issue) @@ -34,7 +34,6 @@ module Issues end def after_update(issue) - add_incident_label(issue) IssuesChannel.broadcast_to(issue, event: 'updated') if Gitlab::ActionCable::Config.in_app? || Feature.enabled?(:broadcast_issue_updates, issue.project) end @@ -127,6 +126,18 @@ module Issues private + def clone_issue(issue) + target_project = params.delete(:target_clone_project) + with_notes = params.delete(:clone_with_notes) + + return unless target_project && + issue.can_clone?(current_user, target_project) + + # we've pre-empted this from running in #execute, so let's go ahead and update the Issue now. + update(issue) + Issues::CloneService.new(project, current_user).execute(issue, target_project, with_notes: with_notes) + end + def create_merge_request_from_quick_action create_merge_request_params = params.delete(:create_merge_request) return unless create_merge_request_params |