Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOswaldo Ferreira <oswaldo@gitlab.com>2017-06-07 23:05:08 +0300
committerOswaldo Ferreira <oswaldo@gitlab.com>2017-06-14 03:07:02 +0300
commit521813f246e31ebe4a406bb340c9df5c55dfa63a (patch)
tree68e73bea195f93fde107f97df68f0605663a03f9 /app/services
parent113666a8d5cd4ba891774738af8a11ed04e4db92 (diff)
Add related issues backend
Diffstat (limited to 'app/services')
-rw-r--r--app/services/issue_links/create_service.rb47
-rw-r--r--app/services/issue_links/destroy_service.rb28
-rw-r--r--app/services/issue_links/list_service.rb58
-rw-r--r--app/services/system_note_service.rb32
4 files changed, 165 insertions, 0 deletions
diff --git a/app/services/issue_links/create_service.rb b/app/services/issue_links/create_service.rb
new file mode 100644
index 00000000000..5f938e61280
--- /dev/null
+++ b/app/services/issue_links/create_service.rb
@@ -0,0 +1,47 @@
+module IssueLinks
+ class CreateService < BaseService
+ def initialize(issue, user, params)
+ @issue, @current_user, @params = issue, user, params.dup
+ end
+
+ def execute
+ if referenced_issues.blank?
+ return error('No Issue found for given reference', 401)
+ end
+
+ create_issue_links
+ success
+ end
+
+ private
+
+ def create_issue_links
+ referenced_issues.each do |referenced_issue|
+ create_notes(referenced_issue) if relate_issues(referenced_issue)
+ end
+ end
+
+ def relate_issues(referenced_issue)
+ IssueLink.create(source: @issue, target: referenced_issue)
+ end
+
+ def create_notes(referenced_issue)
+ SystemNoteService.relate_issue(@issue, referenced_issue, current_user)
+ SystemNoteService.relate_issue(referenced_issue, @issue, current_user)
+ end
+
+ def referenced_issues
+ @referenced_issues ||= begin
+ issue_references = params[:issue_references]
+ text = issue_references.join(' ')
+
+ extractor = Gitlab::ReferenceExtractor.new(@issue.project, @current_user)
+ extractor.analyze(text)
+
+ extractor.issues.select do |issue|
+ can?(current_user, :admin_issue_link, issue)
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/issue_links/destroy_service.rb b/app/services/issue_links/destroy_service.rb
new file mode 100644
index 00000000000..0b08d869c9f
--- /dev/null
+++ b/app/services/issue_links/destroy_service.rb
@@ -0,0 +1,28 @@
+module IssueLinks
+ class DestroyService < BaseService
+ def initialize(issue_link, user)
+ @issue_link = issue_link
+ @current_user = user
+ @issue = issue_link.source
+ @referenced_issue = issue_link.target
+ end
+
+ def execute
+ remove_relation
+ create_notes
+
+ success(message: 'Relation was removed')
+ end
+
+ private
+
+ def remove_relation
+ @issue_link.destroy!
+ end
+
+ def create_notes
+ SystemNoteService.unrelate_issue(@issue, @referenced_issue, current_user)
+ SystemNoteService.unrelate_issue(@referenced_issue, @issue, current_user)
+ end
+ end
+end
diff --git a/app/services/issue_links/list_service.rb b/app/services/issue_links/list_service.rb
new file mode 100644
index 00000000000..609b125c31d
--- /dev/null
+++ b/app/services/issue_links/list_service.rb
@@ -0,0 +1,58 @@
+module IssueLinks
+ class ListService
+ include Gitlab::Routing
+
+ def initialize(issue, user)
+ @issue, @current_user, @project = issue, user, issue.project
+ end
+
+ def execute
+ issues.map do |referenced_issue|
+ {
+ id: referenced_issue.id,
+ title: referenced_issue.title,
+ state: referenced_issue.state,
+ reference: referenced_issue.to_reference(@project),
+ path: namespace_project_issue_path(referenced_issue.project.namespace, referenced_issue.project, referenced_issue.iid),
+ destroy_relation_path: destroy_relation_path(referenced_issue)
+ }
+ end
+ end
+
+ private
+
+ def issues
+ related_issues = Issue
+ .select(['issues.*', 'issue_links.id AS issue_links_id'])
+ .joins("INNER JOIN issue_links ON
+ (issue_links.source_id = issues.id AND issue_links.target_id = #{@issue.id})
+ OR
+ (issue_links.target_id = issues.id AND issue_links.source_id = #{@issue.id})")
+ .preload(project: :namespace)
+ .reorder('issue_links_id')
+
+ Ability.issues_readable_by_user(related_issues, @current_user)
+ end
+
+ def destroy_relation_path(issue)
+ # Make sure the user can admin both the current issue AND the
+ # referenced issue projects in order to return the removal link.
+ if can_destroy_issue_link_on_current_project? && can_destroy_issue_link?(issue.project)
+ namespace_project_issue_link_path(@project.namespace,
+ @issue.project,
+ @issue.iid,
+ issue.issue_links_id)
+ end
+ end
+
+ def can_destroy_issue_link_on_current_project?
+ return @can_destroy_on_current_project if defined?(@can_destroy_on_current_project)
+
+ @can_destroy_on_current_project = can_destroy_issue_link?(@project)
+ end
+
+ def can_destroy_issue_link?(project)
+ Ability.allowed?(@current_user, :admin_issue_link, project)
+ end
+ end
+end
diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb
index 01d572e5efd..ac47f42c6c1 100644
--- a/app/services/system_note_service.rb
+++ b/app/services/system_note_service.rb
@@ -552,6 +552,38 @@ module SystemNoteService
create_note(NoteSummary.new(noteable, project, author, body, action: 'moved'))
end
+ #
+ # noteable - Noteable object
+ # noteable_ref - Referenced noteable object
+ # user - User performing reference
+ #
+ # Example Note text:
+ #
+ # "marked this issue as related to gitlab-ce#9001"
+ #
+ # Returns the created Note object
+ def relate_issue(noteable, noteable_ref, user)
+ body = "marked this issue as related to #{noteable_ref.to_reference(noteable.project)}"
+
+ create_note(NoteSummary.new(noteable, noteable.project, user, body, action: 'relate'))
+ end
+
+ #
+ # noteable - Noteable object
+ # noteable_ref - Referenced noteable object
+ # user - User performing reference
+ #
+ # Example Note text:
+ #
+ # "removed the relation with gitlab-ce#9001"
+ #
+ # Returns the created Note object
+ def unrelate_issue(noteable, noteable_ref, user)
+ body = "removed the relation with #{noteable_ref.to_reference(noteable.project)}"
+
+ create_note(NoteSummary.new(noteable, noteable.project, user, body, action: 'unrelate'))
+ end
+
# Called when the merge request is approved by user
#
# noteable - Noteable object