Module: ActiveProject::Adapters::Jira::Issues

Included in:
ActiveProject::Adapters::JiraAdapter
Defined in:
lib/active_project/adapters/jira/issues.rb

Constant Summary collapse

DEFAULT_FIELDS =
%w[summary description status assignee reporter created updated project issuetype duedate
priority].freeze

Instance Method Summary collapse

Instance Method Details

#adf_text(text) ⇒ Object

Converts plain text to Atlassian Document Format (ADF)



11
12
13
14
15
16
# File 'lib/active_project/adapters/jira/issues.rb', line 11

def adf_text(text)
  {
    type: "doc", version: 1,
    content: [ { type: "paragraph", content: [ { type: "text", text: text } ] } ]
  }
end

#create_issue(_project_id_or_key, attributes) ⇒ ActiveProject::Resources::Issue

Creates a new issue in Jira using the V3 endpoint.

Parameters:

  • _project_id_or_key (String, Integer)

    Ignored (project info is in attributes).

  • attributes (Hash)

    Issue attributes. Required: :project, :summary, :issue_type. Optional: :description, :assignee_id, :due_on, :priority.

Returns:



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/active_project/adapters/jira/issues.rb', line 67

def create_issue(_project_id_or_key, attributes)
  path = "/rest/api/3/issue"

  unless attributes[:project].is_a?(Hash) && (attributes[:project][:id] || attributes[:project][:key]) &&
         attributes[:summary] && !attributes[:summary].empty? &&
         attributes[:issue_type] && (attributes[:issue_type][:id] || attributes[:issue_type][:name])
    raise ArgumentError,
          "Missing required attributes for issue creation: :project (Hash with id/key), " \
          ":summary, :issue_type (with id/name)"
  end

  fields_payload = {
    project: attributes[:project],
    summary: attributes[:summary],
    issuetype: attributes[:issue_type]
  }

  if attributes.key?(:description)
    fields_payload[:description] = if attributes[:description].is_a?(String)
                                     adf_text(attributes[:description])
    elsif attributes[:description].is_a?(Hash)
                                     attributes[:description]
    end
  end

  fields_payload[:assignee] = { accountId: attributes[:assignee_id] } if attributes.key?(:assignee_id)

  if attributes.key?(:due_on)
    fields_payload[:duedate] =
      attributes[:due_on].respond_to?(:strftime) ? attributes[:due_on].strftime("%Y-%m-%d") : attributes[:due_on]
  end

  fields_payload[:priority] = attributes[:priority] if attributes.key?(:priority)

  fields_payload[:parent] = attributes[:parent] if attributes.key?(:parent)

  payload = { fields: fields_payload }.to_json
  response_data = make_request(:post, path, payload)

  find_issue(response_data["key"])
end

#delete_issue(id_or_key, context = {}) ⇒ Boolean

Deletes an issue from Jira.

Parameters:

  • id_or_key (String, Integer)

    The ID or key of the issue to delete.

  • context (Hash) (defaults to: {})

    Optional context. Accepts :delete_subtasks to indicate whether subtasks should be deleted.

Returns:

  • (Boolean)

    True if successfully deleted.



153
154
155
156
157
158
159
160
# File 'lib/active_project/adapters/jira/issues.rb', line 153

def delete_issue(id_or_key, context = {})
  delete_subtasks = context[:delete_subtasks] || false
  path = "/rest/api/3/issue/#{id_or_key}"
  query = { deleteSubtasks: delete_subtasks }

  make_request(:delete, path, nil, query)
  true
end

#find_issue(id_or_key, context = {}) ⇒ ActiveProject::Resources::Issue

Finds a specific issue by its ID or key using the V3 endpoint.

Parameters:

  • id_or_key (String, Integer)

    The ID or key of the issue.

  • context (Hash) (defaults to: {})

    Optional context. Accepts :fields for field selection.

Returns:



52
53
54
55
56
57
58
59
# File 'lib/active_project/adapters/jira/issues.rb', line 52

def find_issue(id_or_key, context = {})
  fields = context[:fields] || DEFAULT_FIELDS
  fields_param = fields.is_a?(Array) ? fields.join(",") : fields
  path = "/rest/api/3/issue/#{id_or_key}?fields=#{fields_param}"

  issue_data = make_request(:get, path)
  map_issue_data(issue_data)
end

#list_issues(project_id_or_key, options = {}) ⇒ Array<ActiveProject::Resources::Issue>

Lists issues within a specific project, optionally filtered by JQL.

Parameters:

  • project_id_or_key (String, Integer)

    The ID or key of the project.

  • options (Hash) (defaults to: {})

    Optional filtering/pagination options. Accepts :jql, :fields, :start_at, :max_results.

Returns:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/active_project/adapters/jira/issues.rb', line 22

def list_issues(project_id_or_key, options = {})
  start_at = options.fetch(:start_at, 0)
  max_results = options.fetch(:max_results, 50)
  jql = options.fetch(:jql, "project = '#{project_id_or_key}' ORDER BY created DESC")
  fields = options[:fields] || DEFAULT_FIELDS

  all_issues = []
  path = "/rest/api/3/search"

  payload = {
    jql: jql,
    startAt: start_at,
    maxResults: max_results,
    fields: fields
  }.to_json

  response_data = make_request(:post, path, payload)

  issues_data = response_data["issues"] || []
  issues_data.each do |issue_data|
    all_issues << map_issue_data(issue_data)
  end

  all_issues
end

#update_issue(id_or_key, attributes, context = {}) ⇒ ActiveProject::Resources::Issue

Updates an existing issue in Jira using the V3 endpoint.

Parameters:

  • id_or_key (String, Integer)

    The ID or key of the issue to update.

  • attributes (Hash)

    Issue attributes to update (e.g., :summary, :description, :assignee_id, :due_on, :priority).

  • context (Hash) (defaults to: {})

    Optional context. Accepts :fields for field selection on return.

Returns:

Raises:

  • (ArgumentError)


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/active_project/adapters/jira/issues.rb', line 114

def update_issue(id_or_key, attributes, context = {})
  raise ArgumentError, "attributes must be a Hash" unless attributes.is_a?(Hash)

  path = "/rest/api/3/issue/#{id_or_key}"

  update_fields = {}
  update_fields[:summary] = attributes[:summary] if attributes.key?(:summary)

  if attributes.key?(:description)
    update_fields[:description] = if attributes[:description].is_a?(String)
                                    adf_text(attributes[:description])
    elsif attributes[:description].is_a?(Hash)
                                    attributes[:description]
    end
  end

  if attributes.key?(:assignee_id)
    update_fields[:assignee] = attributes[:assignee_id] ? { accountId: attributes[:assignee_id] } : nil
  end

  if attributes.key?(:due_on)
    update_fields[:duedate] =
      attributes[:due_on].respond_to?(:strftime) ? attributes[:due_on].strftime("%Y-%m-%d") : attributes[:due_on]
  end

  update_fields[:priority] = attributes[:priority] if attributes.key?(:priority)

  return find_issue(id_or_key, context) if update_fields.empty?

  payload = { fields: update_fields }.to_json
  make_request(:put, path, payload)

  find_issue(id_or_key, context)
end