Class: PlanMyStuff::ProjectItem
- Inherits:
-
ApplicationRecord
- Object
- ApplicationRecord
- PlanMyStuff::ProjectItem
- Defined in:
- lib/plan_my_stuff/project_item.rb
Overview
Wraps a single item within a GitHub Projects V2 project. Stores a reference to its parent Project for delegation.
Class methods:
ProjectItem.create!(issue) -- add existing issue
ProjectItem.create!(title, draft: true, body: "...") -- create draft item
ProjectItem.move_item(item_id:, status:)
ProjectItem.assign(item_id:, assignee:)
Instance methods:
item.move_to!("Done")
item.assign!("octocat")
Instance Attribute Summary collapse
-
#content_node_id ⇒ String?
readonly
Node ID of the underlying content (Issue, PR, or DraftIssue).
- #field_values ⇒ Hash
-
#id ⇒ String
readonly
GitHub node ID (e.g. “PVTI_…”).
-
#issue ⇒ PlanMyStuff::Issue?
Linked issue (nil for draft items).
- #number ⇒ Integer?
- #project ⇒ PlanMyStuff::Project?
- #state ⇒ String?
- #status ⇒ String?
- #title ⇒ String?
-
#type ⇒ String?
readonly
GitHub item type (e.g. “DRAFT_ISSUE”, “ISSUE”, “PULL_REQUEST”).
- #url ⇒ String?
Class Method Summary collapse
-
.assign(number:, content_node_id:, assignees:, draft: false, repo: nil) ⇒ void
Assigns users to a project item.
-
.build(item_hash, project:) ⇒ PlanMyStuff::ProjectItem
Builds a persisted ProjectItem from parsed item data.
-
.create!(issue_or_title, draft: false, body: nil, project_number: nil) ⇒ PlanMyStuff::ProjectItem
Creates a project item by adding an existing issue or creating a draft.
-
.move_item(item_id:, status:, project_number: nil) ⇒ Hash
Moves a project item to a new status column.
Instance Method Summary collapse
-
#assign!(assignees) ⇒ void
Assigns users to this item on its parent project.
- #draft? ⇒ Boolean
-
#initialize(**attrs) ⇒ ProjectItem
constructor
A new instance of ProjectItem.
-
#move_to!(status) ⇒ Hash
Moves this item to a new status column on its parent project.
Methods inherited from ApplicationRecord
Constructor Details
#initialize(**attrs) ⇒ ProjectItem
Returns a new instance of ProjectItem.
362 363 364 365 366 367 368 |
# File 'lib/plan_my_stuff/project_item.rb', line 362 def initialize(**attrs) @id = attrs.delete(:id) @type = attrs.delete(:type) @content_node_id = attrs.delete(:content_node_id) super @field_values ||= {} end |
Instance Attribute Details
#content_node_id ⇒ String? (readonly)
Returns node ID of the underlying content (Issue, PR, or DraftIssue).
21 22 23 |
# File 'lib/plan_my_stuff/project_item.rb', line 21 def content_node_id @content_node_id end |
#field_values ⇒ Hash
37 38 39 |
# File 'lib/plan_my_stuff/project_item.rb', line 37 def field_values @field_values end |
#id ⇒ String (readonly)
Returns GitHub node ID (e.g. “PVTI_…”).
19 20 21 |
# File 'lib/plan_my_stuff/project_item.rb', line 19 def id @id end |
#issue ⇒ PlanMyStuff::Issue?
Returns linked issue (nil for draft items).
41 42 43 |
# File 'lib/plan_my_stuff/project_item.rb', line 41 def issue @issue end |
#number ⇒ Integer?
29 30 31 |
# File 'lib/plan_my_stuff/project_item.rb', line 29 def number @number end |
#project ⇒ PlanMyStuff::Project?
39 40 41 |
# File 'lib/plan_my_stuff/project_item.rb', line 39 def project @project end |
#state ⇒ String?
33 34 35 |
# File 'lib/plan_my_stuff/project_item.rb', line 33 def state @state end |
#status ⇒ String?
35 36 37 |
# File 'lib/plan_my_stuff/project_item.rb', line 35 def status @status end |
#title ⇒ String?
27 28 29 |
# File 'lib/plan_my_stuff/project_item.rb', line 27 def title @title end |
#type ⇒ String? (readonly)
Returns GitHub item type (e.g. “DRAFT_ISSUE”, “ISSUE”, “PULL_REQUEST”).
24 25 26 |
# File 'lib/plan_my_stuff/project_item.rb', line 24 def type @type end |
#url ⇒ String?
31 32 33 |
# File 'lib/plan_my_stuff/project_item.rb', line 31 def url @url end |
Class Method Details
.assign(number:, content_node_id:, assignees:, draft: false, repo: nil) ⇒ void
This method returns an undefined value.
Assigns users to a project item. Issues/PRs use REST via Issue.update!, drafts use GraphQL.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/plan_my_stuff/project_item.rb', line 122 def assign(number:, content_node_id:, assignees:, draft: false, repo: nil) if draft client = PlanMyStuff.client user_ids = assignees.map do |assignee| user_data = client.graphql(user_node_id_query, variables: { login: assignee }) user_id = user_data.dig(:user, :id) raise(APIError, "GitHub user not found: #{assignee}") if user_id.nil? user_id end client.graphql( assign_draft_mutation, variables: { draftIssueId: content_node_id, assigneeIds: user_ids }, ) else Issue.update!(number: number, repo: repo, assignees: assignees) end end |
.build(item_hash, project:) ⇒ PlanMyStuff::ProjectItem
Builds a persisted ProjectItem from parsed item data.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/plan_my_stuff/project_item.rb', line 51 def build(item_hash, project:) item = new( id: item_hash[:id], type: item_hash[:type], content_node_id: item_hash[:content_node_id], title: item_hash[:title], number: item_hash[:number], url: item_hash[:url], state: item_hash[:state], status: item_hash[:status], field_values: item_hash[:field_values] || {}, project: project, ) item.__send__(:persisted!) item end |
.create!(issue_or_title, draft: false, body: nil, project_number: nil) ⇒ PlanMyStuff::ProjectItem
Creates a project item by adding an existing issue or creating a draft.
77 78 79 80 81 82 83 |
# File 'lib/plan_my_stuff/project_item.rb', line 77 def create!(issue_or_title, draft: false, body: nil, project_number: nil) if draft add_draft_item(title: issue_or_title, body: body, project_number: project_number) else add_item(issue: issue_or_title, project_number: project_number) end end |
.move_item(item_id:, status:, project_number: nil) ⇒ Hash
Moves a project item to a new status column.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/plan_my_stuff/project_item.rb', line 93 def move_item(item_id:, status:, project_number: nil) project_number = resolve_default_project_number(project_number) project = Project.find(project_number) status_field = project.status_field option_id = resolve_status_option_id(status_field, status) PlanMyStuff.client.graphql( update_single_select_mutation, variables: { projectId: project.id, itemId: item_id, fieldId: status_field[:id], optionId: option_id, }, ) end |
Instance Method Details
#assign!(assignees) ⇒ void
This method returns an undefined value.
Assigns users to this item on its parent project.
390 391 392 393 394 395 396 397 |
# File 'lib/plan_my_stuff/project_item.rb', line 390 def assign!(assignees) self.class.assign( number: number, content_node_id: content_node_id, assignees: Array.wrap(assignees), draft: draft?, ) end |
#draft? ⇒ Boolean
400 401 402 |
# File 'lib/plan_my_stuff/project_item.rb', line 400 def draft? type == 'DRAFT_ISSUE' end |
#move_to!(status) ⇒ Hash
Moves this item to a new status column on its parent project.
376 377 378 379 380 381 382 |
# File 'lib/plan_my_stuff/project_item.rb', line 376 def move_to!(status) self.class.move_item( project_number: project.number, item_id: id, status: status, ) end |