Class: PlanMyStuff::IssueField

Inherits:
Object
  • Object
show all
Defined in:
lib/plan_my_stuff/issue_field.rb

Overview

Value object wrapping an organization-level GitHub Issue Field definition (public preview). Issue Fields are structured per-issue metadata (text, number, date, or single-select) configured once at the org level and applied across all of the org’s repositories.

Read-only on the gem side: callers manage field definitions through the GitHub UI, while the gem only handles field values on individual issues (see Issue#issue_fields).

Constant Summary collapse

TYPES =

GraphQL __typename -> normalized type symbol used internally.

{
  IssueFieldText: :text,
  IssueFieldNumber: :number,
  IssueFieldDate: :date,
  IssueFieldSingleSelect: :single_select,
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id:, name:, type:, description: nil, options: []) ⇒ IssueField

Returns a new instance of IssueField.

Parameters:

  • id (String)
  • name (String)
  • type (Symbol)
  • description (String, nil) (defaults to: nil)
  • options (Array<Hash>) (defaults to: [])


101
102
103
104
105
106
107
# File 'lib/plan_my_stuff/issue_field.rb', line 101

def initialize(id:, name:, type:, description: nil, options: [])
  @id = id
  @name = name
  @type = type
  @description = description
  @options = options
end

Instance Attribute Details

#descriptionString? (readonly)

Returns:

  • (String, nil)


29
30
31
# File 'lib/plan_my_stuff/issue_field.rb', line 29

def description
  @description
end

#idString (readonly)

Returns GraphQL node ID, e.g. “IFSS_kgDOAAGskA”.

Returns:

  • (String)

    GraphQL node ID, e.g. “IFSS_kgDOAAGskA”



20
21
22
# File 'lib/plan_my_stuff/issue_field.rb', line 20

def id
  @id
end

#nameString (readonly)

Returns display name (e.g. “Priority”).

Returns:

  • (String)

    display name (e.g. “Priority”)



23
24
25
# File 'lib/plan_my_stuff/issue_field.rb', line 23

def name
  @name
end

#optionsArray<Hash> (readonly)

Returns for :single_select, the option list as returned by GraphQL with symbol keys (id, name, description, color). Empty for other field types.

Returns:

  • (Array<Hash>)

    for :single_select, the option list as returned by GraphQL with symbol keys (id, name, description, color). Empty for other field types.



33
34
35
# File 'lib/plan_my_stuff/issue_field.rb', line 33

def options
  @options
end

#typeSymbol (readonly)

Returns one of :text, :number, :date, :single_select.

Returns:

  • (Symbol)

    one of :text, :number, :date, :single_select



26
27
28
# File 'lib/plan_my_stuff/issue_field.rb', line 26

def type
  @type
end

Class Method Details

.find(name, org: nil) ⇒ PlanMyStuff::IssueField?

Parameters:

  • name (String, Symbol)
  • org (String, nil) (defaults to: nil)

Returns:



60
61
62
# File 'lib/plan_my_stuff/issue_field.rb', line 60

def find(name, org: nil)
  list(org: org).find { |field| field.name.casecmp?(name.to_s) }
end

.from_graphql(node) ⇒ PlanMyStuff::IssueField

Parameters:

  • node (Hash)

    one node from LIST_ORG_ISSUE_FIELDS

Returns:

Raises:



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/plan_my_stuff/issue_field.rb', line 68

def from_graphql(node)
  typename = node[:__typename]
  type = TYPES[typename.to_sym] if typename
  raise(PlanMyStuff::Error, "Unknown Issue Field typename: #{typename.inspect}") if type.nil?

  new(
    id: node.fetch(:id),
    name: node.fetch(:name),
    type: type,
    description: node[:description],
    options: Array.wrap(node[:options]),
  )
end

.list(org: nil) ⇒ Array<PlanMyStuff::IssueField>

Lists Issue Field definitions configured on the org.

Parameters:

  • org (String, nil) (defaults to: nil)

    org login; defaults to config.organization

Returns:

Raises:



44
45
46
47
48
49
50
51
52
53
# File 'lib/plan_my_stuff/issue_field.rb', line 44

def list(org: nil)
  ensure_enabled!

   = org || PlanMyStuff.configuration.organization
  data = PlanMyStuff.client.graphql(
    PlanMyStuff::GraphQL::Queries::LIST_ORG_ISSUE_FIELDS,
    variables: { org:  },
  )
  Array.wrap(data.dig(:organization, :issueFields, :nodes)).map { |node| from_graphql(node) }
end

Instance Method Details

#option_id_for!(option_name) ⇒ String

Resolves a single-select option name to its GraphQL node ID.

Parameters:

  • option_name (String, Symbol)

Returns:

  • (String)

Raises:

  • (PlanMyStuff::Error)

    if this field is not a single-select, or the option name is unknown



117
118
119
120
121
122
123
124
# File 'lib/plan_my_stuff/issue_field.rb', line 117

def option_id_for!(option_name)
  raise(PlanMyStuff::Error, "Field #{name.inspect} is not a single-select") unless type == :single_select

  match = options.find { |option| option.fetch(:name).casecmp?(option_name.to_s) }
  raise(PlanMyStuff::Error, "Unknown option #{option_name.inspect} for field #{name.inspect}") if match.nil?

  match.fetch(:id)
end