diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 01:45:44 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-19 01:45:44 +0000 |
commit | 85dc423f7090da0a52c73eb66faf22ddb20efff9 (patch) | |
tree | 9160f299afd8c80c038f08e1545be119f5e3f1e1 /app/services/issuable_links | |
parent | 15c2c8c66dbe422588e5411eee7e68f1fa440bb8 (diff) | |
download | gitlab-ce-85dc423f7090da0a52c73eb66faf22ddb20efff9.tar.gz |
Add latest changes from gitlab-org/gitlab@13-4-stable-ee
Diffstat (limited to 'app/services/issuable_links')
-rw-r--r-- | app/services/issuable_links/create_service.rb | 119 | ||||
-rw-r--r-- | app/services/issuable_links/destroy_service.rb | 34 | ||||
-rw-r--r-- | app/services/issuable_links/list_service.rb | 27 |
3 files changed, 180 insertions, 0 deletions
diff --git a/app/services/issuable_links/create_service.rb b/app/services/issuable_links/create_service.rb new file mode 100644 index 00000000000..f148c503dcf --- /dev/null +++ b/app/services/issuable_links/create_service.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +module IssuableLinks + class CreateService < BaseService + include IncidentManagement::UsageData + + attr_reader :issuable, :current_user, :params + + def initialize(issuable, user, params) + @issuable, @current_user, @params = issuable, user, params.dup + end + + def execute + # If ALL referenced issues are already assigned to the given epic it renders a conflict status, + # otherwise create issue links for the issues which + # are still not assigned and return success message. + if render_conflict_error? + return error(issuables_assigned_message, 409) + end + + if render_not_found_error? + return error(issuables_not_found_message, 404) + end + + @errors = [] + create_links + + if @errors.present? + return error(@errors.join('. '), 422) + end + + track_event + + success + end + + private + + def render_conflict_error? + referenced_issuables.present? && (referenced_issuables - previous_related_issuables).empty? + end + + def render_not_found_error? + linkable_issuables(referenced_issuables).empty? + end + + def create_links + objects = linkable_issuables(referenced_issuables) + link_issuables(objects) + end + + def link_issuables(target_issuables) + target_issuables.each do |referenced_object| + link = relate_issuables(referenced_object) + + unless link.valid? + @errors << _("%{ref} cannot be added: %{error}") % { + ref: referenced_object.to_reference, + error: link.errors.messages.values.flatten.to_sentence + } + end + end + end + + def referenced_issuables + @referenced_issuables ||= begin + target_issuable = params[:target_issuable] + + if params[:issuable_references].present? + extract_references + elsif target_issuable + [target_issuable] + else + [] + end + end + end + + def extract_references + issuable_references = params[:issuable_references] + text = issuable_references.join(' ') + + extractor = Gitlab::ReferenceExtractor.new(issuable.project, current_user) + extractor.analyze(text, extractor_context) + + references(extractor) + end + + def references(extractor) + extractor.issues + end + + def extractor_context + {} + end + + def linkable_issuables(objects) + raise NotImplementedError + end + + def previous_related_issuables + raise NotImplementedError + end + + def relate_issuables(referenced_object) + raise NotImplementedError + end + + def issuables_assigned_message + 'Issue(s) already assigned' + end + + def issuables_not_found_message + 'No Issue found for given params' + end + end +end + +IssuableLinks::CreateService.prepend_if_ee('EE::IssuableLinks::CreateService') diff --git a/app/services/issuable_links/destroy_service.rb b/app/services/issuable_links/destroy_service.rb new file mode 100644 index 00000000000..57e1314e0da --- /dev/null +++ b/app/services/issuable_links/destroy_service.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module IssuableLinks + class DestroyService < BaseService + include IncidentManagement::UsageData + + attr_reader :link, :current_user + + def initialize(link, user) + @link = link + @current_user = user + end + + def execute + return error(not_found_message, 404) unless permission_to_remove_relation? + + remove_relation + create_notes + track_event + + success(message: 'Relation was removed') + end + + private + + def remove_relation + link.destroy! + end + + def not_found_message + 'No Issue Link found' + end + end +end diff --git a/app/services/issuable_links/list_service.rb b/app/services/issuable_links/list_service.rb new file mode 100644 index 00000000000..10a2da7eb03 --- /dev/null +++ b/app/services/issuable_links/list_service.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module IssuableLinks + class ListService + include Gitlab::Routing + + attr_reader :issuable, :current_user + + def initialize(issuable, user) + @issuable, @current_user = issuable, user + end + + def execute + serializer.new(current_user: current_user, issuable: issuable).represent(child_issuables) + end + + private + + def serializer + raise NotImplementedError + end + + def preload_for_collection + [{ project: :namespace }, :assignees] + end + end +end |