Class: PlanMyStuff::Project
- Inherits:
-
ApplicationRecord
- Object
- ApplicationRecord
- PlanMyStuff::Project
- Defined in:
- lib/plan_my_stuff/project.rb
Overview
Wraps a GitHub Projects V2 project with its statuses, items, and fields. Class methods provide the public API for CRUD and query operations.
Follows an ActiveRecord-style pattern:
-
‘Project.find` / `Project.list` return persisted instances
-
‘ProjectItem.add_item` / `ProjectItem.add_draft_item` for adding items
-
‘ProjectItem.move_item` / `ProjectItem.assign` for item mutations
Constant Summary collapse
- MAX_AUTO_PAGINATE_ITEMS =
500- ITEMS_PER_PAGE =
100
Instance Attribute Summary collapse
-
#closed ⇒ Boolean
readonly
Whether the project is closed.
-
#fields ⇒ Array<Hash>
All field definitions.
-
#has_next_page ⇒ Boolean?
Whether more pages exist (only in cursor mode).
-
#id ⇒ String
readonly
GitHub node ID.
-
#items ⇒ Array<PlanMyStuff::ProjectItem>
Project items.
-
#next_cursor ⇒ String?
Cursor for next page (only in cursor mode).
-
#number ⇒ Integer
readonly
Project number.
-
#statuses ⇒ Array<Hash>
Status options (name:).
-
#title ⇒ String
Project title.
-
#url ⇒ String
Project URL.
Class Method Summary collapse
-
.create(title:) ⇒ Object
Creates a new project in the configured organization.
-
.find(number, paginate: :auto, cursor: nil) ⇒ PlanMyStuff::Project
Finds a project by number with its statuses, items, and fields.
-
.list ⇒ Array<PlanMyStuff::Project>
Lists all projects in the configured organization.
-
.update(project_number:, title: nil) ⇒ Object
Updates an existing project.
Instance Method Summary collapse
-
#initialize(**attrs) ⇒ Project
constructor
A new instance of Project.
-
#status_field ⇒ Hash
Returns the Status single-select field definition.
Methods inherited from ApplicationRecord
Constructor Details
#initialize(**attrs) ⇒ Project
Returns a new instance of Project.
410 411 412 413 414 415 416 417 418 |
# File 'lib/plan_my_stuff/project.rb', line 410 def initialize(**attrs) @id = attrs.delete(:id) @number = attrs.delete(:number) @closed = attrs.delete(:closed) super @statuses ||= [] @fields ||= [] @items ||= [] end |
Instance Attribute Details
#closed ⇒ Boolean (readonly)
Returns whether the project is closed.
20 21 22 |
# File 'lib/plan_my_stuff/project.rb', line 20 def closed @closed end |
#fields ⇒ Array<Hash>
Returns all field definitions.
29 30 31 |
# File 'lib/plan_my_stuff/project.rb', line 29 def fields @fields end |
#has_next_page ⇒ Boolean?
Returns whether more pages exist (only in cursor mode).
35 36 37 |
# File 'lib/plan_my_stuff/project.rb', line 35 def has_next_page @has_next_page end |
#id ⇒ String (readonly)
Returns GitHub node ID.
16 17 18 |
# File 'lib/plan_my_stuff/project.rb', line 16 def id @id end |
#items ⇒ Array<PlanMyStuff::ProjectItem>
Returns project items.
31 32 33 |
# File 'lib/plan_my_stuff/project.rb', line 31 def items @items end |
#next_cursor ⇒ String?
Returns cursor for next page (only in cursor mode).
33 34 35 |
# File 'lib/plan_my_stuff/project.rb', line 33 def next_cursor @next_cursor end |
#number ⇒ Integer (readonly)
Returns project number.
18 19 20 |
# File 'lib/plan_my_stuff/project.rb', line 18 def number @number end |
#statuses ⇒ Array<Hash>
Returns status options (name:).
27 28 29 |
# File 'lib/plan_my_stuff/project.rb', line 27 def statuses @statuses end |
#title ⇒ String
Returns project title.
23 24 25 |
# File 'lib/plan_my_stuff/project.rb', line 23 def title @title end |
#url ⇒ String
Returns project URL.
25 26 27 |
# File 'lib/plan_my_stuff/project.rb', line 25 def url @url end |
Class Method Details
.create(title:) ⇒ Object
Creates a new project in the configured organization.
44 45 46 |
# File 'lib/plan_my_stuff/project.rb', line 44 def create(title:) raise(NotImplementedError, "#{name}.create is not yet implemented") end |
.find(number, paginate: :auto, cursor: nil) ⇒ PlanMyStuff::Project
Finds a project by number with its statuses, items, and fields.
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/plan_my_stuff/project.rb', line 80 def find(number, paginate: :auto, cursor: nil) org = PlanMyStuff.configuration.organization case paginate when :auto find_auto_paginated(org, number) when :cursor find_with_cursor(org, number, cursor: cursor) else raise(ArgumentError, "Unknown paginate mode: #{paginate.inspect}. Use :auto or :cursor") end end |
.list ⇒ Array<PlanMyStuff::Project>
Lists all projects in the configured organization.
63 64 65 66 67 68 69 70 |
# File 'lib/plan_my_stuff/project.rb', line 63 def list org = PlanMyStuff.configuration.organization data = PlanMyStuff.client.graphql(list_query, variables: { org: org }) nodes = data.dig(:organization, :projectsV2, :nodes) || [] nodes.map { |node| build_summary(node) } end |
.update(project_number:, title: nil) ⇒ Object
Updates an existing project.
55 56 57 |
# File 'lib/plan_my_stuff/project.rb', line 55 def update(project_number:, title: nil) raise(NotImplementedError, "#{name}.update is not yet implemented") end |
Instance Method Details
#status_field ⇒ Hash
Returns the Status single-select field definition.
426 427 428 429 430 431 432 |
# File 'lib/plan_my_stuff/project.rb', line 426 def status_field field = fields.find { |f| f[:name] == 'Status' && f[:options] } raise(APIError, "No 'Status' field found on project ##{number}") unless field field end |