ruby-trello 2.0.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +106 -17
- data/lib/trello.rb +47 -34
- data/lib/trello/action.rb +10 -8
- data/lib/trello/association_builder/has_many.rb +17 -0
- data/lib/trello/association_builder/has_one.rb +16 -0
- data/lib/trello/association_fetcher/has_many.rb +26 -0
- data/lib/trello/association_fetcher/has_many/fetch.rb +47 -0
- data/lib/trello/association_fetcher/has_many/params.rb +56 -0
- data/lib/trello/association_fetcher/has_one.rb +25 -0
- data/lib/trello/association_fetcher/has_one/fetch.rb +49 -0
- data/lib/trello/association_fetcher/has_one/params.rb +36 -0
- data/lib/trello/association_infer_tool.rb +13 -0
- data/lib/trello/association_proxy.rb +1 -1
- data/lib/trello/attachment.rb +13 -10
- data/lib/trello/basic_data.rb +16 -49
- data/lib/trello/board.rb +17 -3
- data/lib/trello/card.rb +103 -38
- data/lib/trello/checklist.rb +14 -13
- data/lib/trello/client.rb +1 -1
- data/lib/trello/comment.rb +4 -4
- data/lib/trello/custom_field.rb +131 -0
- data/lib/trello/custom_field_item.rb +98 -0
- data/lib/trello/custom_field_option.rb +22 -0
- data/lib/trello/error.rb +12 -0
- data/lib/trello/item.rb +7 -7
- data/lib/trello/item_state.rb +3 -3
- data/lib/trello/label.rb +30 -12
- data/lib/trello/label_name.rb +10 -10
- data/lib/trello/list.rb +6 -6
- data/lib/trello/member.rb +10 -9
- data/lib/trello/notification.rb +6 -6
- data/lib/trello/organization.rb +11 -11
- data/lib/trello/plugin_datum.rb +6 -6
- data/lib/trello/register_attributes.rb +54 -0
- data/lib/trello/token.rb +6 -5
- data/lib/trello/webhook.rb +5 -5
- data/spec/action_spec.rb +22 -1
- data/spec/basic_data_spec.rb +58 -0
- data/spec/board_spec.rb +28 -2
- data/spec/card_spec.rb +183 -8
- data/spec/cassettes/can_add_a_file_from_url_on_a_card.yml +189 -0
- data/spec/cassettes/can_add_a_file_on_a_card.yml +200 -0
- data/spec/cassettes/can_add_a_member_to_a_card.yml +190 -0
- data/spec/cassettes/can_add_label_on_a_card.yml +281 -0
- data/spec/cassettes/can_close_bong_a_card.yml +189 -0
- data/spec/cassettes/can_get_actions.yml +196 -0
- data/spec/cassettes/can_get_attachments.yml +187 -0
- data/spec/cassettes/can_get_comments.yml +193 -0
- data/spec/cassettes/can_move_a_card_to_another_board_with_specific_list.yml +373 -0
- data/spec/cassettes/can_move_a_card_to_another_board_without_specific_list.yml +281 -0
- data/spec/cassettes/can_move_a_card_to_another_list.yml +281 -0
- data/spec/cassettes/can_remove_a_member_from_a_card.yml +185 -0
- data/spec/cassettes/can_remove_an_attachment_on_a_card.yml +277 -0
- data/spec/cassettes/can_remove_an_upvote_on_a_card.yml +465 -0
- data/spec/cassettes/can_remove_label_on_a_card.yml +279 -0
- data/spec/cassettes/can_success_add_comment_to_a_card.yml +196 -0
- data/spec/cassettes/can_success_copy_checklist_to_a_card.yml +281 -0
- data/spec/cassettes/can_success_copy_checklist_to_a_card_without_name_pos.yml +281 -0
- data/spec/cassettes/can_success_create_a_card.yml +99 -0
- data/spec/cassettes/can_success_create_new_checklist_to_a_card.yml +189 -0
- data/spec/cassettes/can_success_delete_card.yml +185 -0
- data/spec/cassettes/can_success_upate_a_card.yml +189 -0
- data/spec/cassettes/can_success_update_bong_a_board.yml +283 -0
- data/spec/cassettes/can_success_update_bong_a_card.yml +191 -0
- data/spec/cassettes/can_upvote_on_a_card.yml +469 -0
- data/spec/cassettes/card_find_with_id_and_get_all_fields.yml +95 -0
- data/spec/cassettes/card_find_with_id_and_get_specific_fields.yml +96 -0
- data/spec/cassettes/custom_field_item_save_1.yml +97 -0
- data/spec/cassettes/custom_field_item_save_2.yml +281 -0
- data/spec/cassettes/get_board_of_card.yml +187 -0
- data/spec/cassettes/get_check_item_states_of_card.yml +188 -0
- data/spec/cassettes/get_checklists_of_card.yml +187 -0
- data/spec/cassettes/get_cover_image_of_card.yml +187 -0
- data/spec/cassettes/get_custom_field_items_of_card.yml +187 -0
- data/spec/cassettes/get_list_of_card.yml +188 -0
- data/spec/cassettes/get_lists.yml +187 -0
- data/spec/cassettes/get_members_of_card.yml +189 -0
- data/spec/cassettes/get_plugin_data_of_card.yml +187 -0
- data/spec/cassettes/get_voters_of_card.yml +188 -0
- data/spec/cassettes/remove_upvote_on_a_card_when_have_not_voted.yml +366 -0
- data/spec/cassettes/revote_on_a_card.yml +464 -0
- data/spec/checklist_spec.rb +39 -3
- data/spec/client_spec.rb +5 -1
- data/spec/custom_field_item_spec.rb +192 -0
- data/spec/custom_field_option_spec.rb +49 -0
- data/spec/custom_field_spec.rb +261 -0
- data/spec/integration/basic_data/many_spec.rb +123 -0
- data/spec/integration/basic_data/one_spec.rb +84 -0
- data/spec/integration/basic_data/register_attributes_spec.rb +75 -0
- data/spec/integration/board/update!_spec.rb +31 -0
- data/spec/integration/board_lists_spec.rb +21 -0
- data/spec/integration/card/add_and_remove_attachment_spec.rb +45 -0
- data/spec/integration/card/add_and_remove_label_spec.rb +35 -0
- data/spec/integration/card/add_checklist_spec.rb +32 -0
- data/spec/integration/card/add_comment_spec.rb +19 -0
- data/spec/integration/card/add_memeber_spec.rb +19 -0
- data/spec/integration/card/associations/actions_spec.rb +17 -0
- data/spec/integration/card/associations/attachments_spec.rb +18 -0
- data/spec/integration/card/associations/board_spec.rb +17 -0
- data/spec/integration/card/associations/check_item_states_spec.rb +17 -0
- data/spec/integration/card/associations/checklists_spec.rb +18 -0
- data/spec/integration/card/associations/comments_spec.rb +19 -0
- data/spec/integration/card/associations/cover_image_spec.rb +18 -0
- data/spec/integration/card/associations/custom_field_items_spec.rb +18 -0
- data/spec/integration/card/associations/list_spec.rb +16 -0
- data/spec/integration/card/associations/members_spec.rb +18 -0
- data/spec/integration/card/associations/plugin_data_spec.rb +18 -0
- data/spec/integration/card/associations/voters_spec.rb +17 -0
- data/spec/integration/card/close!_spec.rb +16 -0
- data/spec/integration/card/create_new_check_list_spec.rb +19 -0
- data/spec/integration/card/create_spec.rb +50 -0
- data/spec/integration/card/delete_spec.rb +16 -0
- data/spec/integration/card/find_spec.rb +67 -0
- data/spec/integration/card/move_to_board_spec.rb +36 -0
- data/spec/integration/card/move_to_list_spec.rb +20 -0
- data/spec/integration/card/remove_member_spec.rb +19 -0
- data/spec/integration/card/save_spec.rb +61 -0
- data/spec/integration/card/update!_spec.rb +53 -0
- data/spec/integration/card/vote_spec.rb +50 -0
- data/spec/integration/custom_field_item_spec.rb +47 -0
- data/spec/item_spec.rb +20 -0
- data/spec/label_spec.rb +99 -0
- data/spec/list_spec.rb +21 -0
- data/spec/member_spec.rb +23 -0
- data/spec/notification_spec.rb +21 -0
- data/spec/organization_spec.rb +26 -0
- data/spec/spec_helper.rb +96 -23
- data/spec/token_spec.rb +19 -0
- data/spec/unit/trello/association_builder/has_many_spec.rb +36 -0
- data/spec/unit/trello/association_builder/has_one_spec.rb +36 -0
- data/spec/unit/trello/association_fetcher/has_many/fetch_spec.rb +38 -0
- data/spec/unit/trello/association_fetcher/has_many/params_spec.rb +107 -0
- data/spec/unit/trello/association_fetcher/has_many_spec.rb +50 -0
- data/spec/unit/trello/association_fetcher/has_one/fetch_spec.rb +51 -0
- data/spec/unit/trello/association_fetcher/has_one/params_spec.rb +81 -0
- data/spec/unit/trello/association_fetcher/has_one_spec.rb +49 -0
- data/spec/unit/trello/association_infer_tool_spec.rb +41 -0
- data/spec/unit/trello/basic_data_spec.rb +54 -0
- data/spec/unit/trello/card_spec.rb +103 -0
- data/spec/webhook_spec.rb +20 -0
- metadata +224 -30
@@ -0,0 +1,25 @@
|
|
1
|
+
module Trello
|
2
|
+
module AssociationFetcher
|
3
|
+
class HasOne
|
4
|
+
autoload :Params, 'trello/association_fetcher/has_one/params'
|
5
|
+
autoload :Fetch, 'trello/association_fetcher/has_one/fetch'
|
6
|
+
|
7
|
+
attr_reader :model, :name, :options
|
8
|
+
|
9
|
+
def initialize(model, name, options)
|
10
|
+
@model = model
|
11
|
+
@name = name
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch
|
16
|
+
params = Params.new(
|
17
|
+
association_owner: model,
|
18
|
+
association_name: name,
|
19
|
+
association_options: options
|
20
|
+
)
|
21
|
+
Fetch.execute(params)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Trello
|
2
|
+
module AssociationFetcher
|
3
|
+
class HasOne
|
4
|
+
class Fetch
|
5
|
+
class << self
|
6
|
+
def execute(params)
|
7
|
+
new(params).execute
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(params)
|
12
|
+
@params = params
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute
|
16
|
+
if association_restful_name
|
17
|
+
client.find(association_restful_name, association_restful_id)
|
18
|
+
else
|
19
|
+
association_class.find(association_restful_id)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :params
|
26
|
+
|
27
|
+
def client
|
28
|
+
association_owner.client
|
29
|
+
end
|
30
|
+
|
31
|
+
def association_owner
|
32
|
+
params.association_owner
|
33
|
+
end
|
34
|
+
|
35
|
+
def association_restful_name
|
36
|
+
params.association_restful_name
|
37
|
+
end
|
38
|
+
|
39
|
+
def association_restful_id
|
40
|
+
params.association_restful_id
|
41
|
+
end
|
42
|
+
|
43
|
+
def association_class
|
44
|
+
params.association_class
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Trello
|
2
|
+
module AssociationFetcher
|
3
|
+
class HasOne
|
4
|
+
class Params
|
5
|
+
attr_reader :association_owner
|
6
|
+
|
7
|
+
def initialize(association_owner:, association_name:, association_options:)
|
8
|
+
@association_owner = association_owner
|
9
|
+
@association_name = association_name
|
10
|
+
@association_options = association_options || {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def association_class
|
14
|
+
association_options[:via] || infer_class_on(association_name)
|
15
|
+
end
|
16
|
+
|
17
|
+
def association_restful_name
|
18
|
+
association_options[:path]
|
19
|
+
end
|
20
|
+
|
21
|
+
def association_restful_id
|
22
|
+
id_field = association_options[:using] || :id
|
23
|
+
association_owner.send(id_field)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :association_name, :association_options
|
29
|
+
|
30
|
+
def infer_class_on(name)
|
31
|
+
AssociationInferTool.infer_class_on_name(name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Trello
|
2
|
+
class AssociationInferTool
|
3
|
+
class << self
|
4
|
+
def infer_restful_resource_on_class(klass)
|
5
|
+
klass.to_s.split('::').last.downcase.pluralize
|
6
|
+
end
|
7
|
+
|
8
|
+
def infer_class_on_name(name)
|
9
|
+
Trello.const_get(name.to_s.singularize.camelize)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/trello/attachment.rb
CHANGED
@@ -7,6 +7,8 @@ module Trello
|
|
7
7
|
# @return [String]
|
8
8
|
# @!attribute url
|
9
9
|
# @return [String]
|
10
|
+
# @!attribute pos
|
11
|
+
# @return [Float]
|
10
12
|
# @!attribute bytes
|
11
13
|
# @return [Fixnum]
|
12
14
|
# @!attribute date
|
@@ -16,21 +18,22 @@ module Trello
|
|
16
18
|
# @!attribute mime_type
|
17
19
|
# @return [String]
|
18
20
|
class Attachment < BasicData
|
19
|
-
register_attributes :name, :id, :url, :bytes, :member_id, :date, :is_upload, :mime_type, :previews
|
21
|
+
register_attributes :name, :id, :pos, :url, :bytes, :member_id, :date, :is_upload, :mime_type, :previews
|
20
22
|
# Update the fields of an attachment.
|
21
23
|
#
|
22
24
|
# Supply a hash of stringkeyed data retrieved from the Trello API representing
|
23
25
|
# an attachment.
|
24
26
|
def update_fields(fields)
|
25
|
-
attributes[:name] = fields['name']
|
26
|
-
attributes[:id] = fields['id']
|
27
|
-
attributes[:
|
28
|
-
attributes[:
|
29
|
-
attributes[:
|
30
|
-
attributes[:
|
31
|
-
attributes[:
|
32
|
-
attributes[:
|
33
|
-
attributes[:
|
27
|
+
attributes[:name] = fields['name'] || attributes[:name]
|
28
|
+
attributes[:id] = fields['id'] || attributes[:id]
|
29
|
+
attributes[:pos] = fields['pos'] || attributes[:pos]
|
30
|
+
attributes[:url] = fields['url'] || attributes[:url]
|
31
|
+
attributes[:bytes] = fields['bytes'].to_i || attributes[:bytes]
|
32
|
+
attributes[:member_id] = fields['idMember'] || attributes[:member_id]
|
33
|
+
attributes[:date] = Time.parse(fields['date']).presence || attributes[:date]
|
34
|
+
attributes[:is_upload] = fields['isUpload'] if fields.has_key?('isUpload')
|
35
|
+
attributes[:mime_type] = fields['mimeType'] || attributes[:mime_type]
|
36
|
+
attributes[:previews] = fields['previews'] if fields.has_key?('previews')
|
34
37
|
self
|
35
38
|
end
|
36
39
|
end
|
data/lib/trello/basic_data.rb
CHANGED
@@ -42,61 +42,20 @@ module Trello
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
def self.register_attributes(*
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
# Defines the attribute getter and setters.
|
50
|
-
class_eval do
|
51
|
-
define_method :attributes do
|
52
|
-
@attributes ||= names.reduce({}) { |hash, k| hash.merge(k.to_sym => nil) }
|
53
|
-
end
|
54
|
-
|
55
|
-
names.each do |key|
|
56
|
-
define_method(:"#{key}") { @attributes[key] }
|
45
|
+
def self.register_attributes(*names_and_options)
|
46
|
+
has_opts = names_and_options.last.kind_of?(Hash)
|
47
|
+
readonly_attributes = has_opts ? names_and_options.pop[:readonly] : []
|
48
|
+
attributes = names_and_options
|
57
49
|
|
58
|
-
|
59
|
-
define_method :"#{key}=" do |val|
|
60
|
-
send(:"#{key}_will_change!") unless val == @attributes[key]
|
61
|
-
@attributes[key] = val
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
define_attribute_methods names
|
67
|
-
end
|
50
|
+
RegisterAttributes.execute(self, attributes, readonly_attributes)
|
68
51
|
end
|
69
52
|
|
70
53
|
def self.one(name, opts = {})
|
71
|
-
|
72
|
-
define_method(:"#{name}") do |*args|
|
73
|
-
options = opts.dup
|
74
|
-
klass = options.delete(:via) || Trello.const_get(name.to_s.camelize)
|
75
|
-
ident = options.delete(:using) || :id
|
76
|
-
path = options.delete(:path)
|
77
|
-
|
78
|
-
if path
|
79
|
-
client.find(path, self.send(ident))
|
80
|
-
else
|
81
|
-
klass.find(self.send(ident))
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
54
|
+
AssociationBuilder::HasOne.build(self, name, opts)
|
85
55
|
end
|
86
56
|
|
87
57
|
def self.many(name, opts = {})
|
88
|
-
|
89
|
-
define_method(:"#{name}") do |*args|
|
90
|
-
options = opts.dup
|
91
|
-
resource = options.delete(:in) || self.class.to_s.split("::").last.downcase.pluralize
|
92
|
-
klass = options.delete(:via) || Trello.const_get(name.to_s.singularize.camelize)
|
93
|
-
path = options.delete(:path) || name
|
94
|
-
params = options.merge(args[0] || {})
|
95
|
-
|
96
|
-
resources = client.find_many(klass, "/#{resource}/#{id}/#{path}", params)
|
97
|
-
MultiAssociation.new(self, resources).proxy
|
98
|
-
end
|
99
|
-
end
|
58
|
+
AssociationBuilder::HasMany.build(self, name, opts)
|
100
59
|
end
|
101
60
|
|
102
61
|
def self.client
|
@@ -122,7 +81,15 @@ module Trello
|
|
122
81
|
|
123
82
|
# Two objects are equal if their _id_ methods are equal.
|
124
83
|
def ==(other)
|
125
|
-
id == other.id
|
84
|
+
self.class == other.class && id == other.id
|
85
|
+
end
|
86
|
+
|
87
|
+
# Alias hash equality to equality
|
88
|
+
alias eql? ==
|
89
|
+
|
90
|
+
# Delegate hash key computation to class and id pair
|
91
|
+
def hash
|
92
|
+
[self.class, id].hash
|
126
93
|
end
|
127
94
|
|
128
95
|
def client
|
data/lib/trello/board.rb
CHANGED
@@ -72,11 +72,12 @@ module Trello
|
|
72
72
|
fail "Cannot save new instance." unless self.id
|
73
73
|
|
74
74
|
@previously_changed = changes
|
75
|
-
@changed_attributes.clear
|
75
|
+
@changed_attributes.clear if @changed_attributes.respond_to?(:clear)
|
76
|
+
changes_applied if respond_to?(:changes_applied)
|
76
77
|
|
77
78
|
fields = {
|
78
79
|
name: attributes[:name],
|
79
|
-
|
80
|
+
desc: attributes[:description],
|
80
81
|
closed: attributes[:closed],
|
81
82
|
starred: attributes[:starred],
|
82
83
|
idOrganization: attributes[:organization_id]
|
@@ -151,12 +152,25 @@ module Trello
|
|
151
152
|
#
|
152
153
|
# This method, when called, can take a hash table with a filter key containing any
|
153
154
|
# of the following values:
|
154
|
-
# :filter => [ :none, :normal, :owners, :all ] # default :all
|
155
|
+
# :filter => [ :none, :normal, :owners, :admins, :all ] # default :all
|
155
156
|
many :members, filter: :all
|
156
157
|
|
158
|
+
# Returns a list of checklists associated with the board.
|
159
|
+
#
|
160
|
+
# The options hash may have a filter key which can have its value set as any
|
161
|
+
# of the following values:
|
162
|
+
# :filter => [ :none, :all ] # default :all
|
163
|
+
many :checklists, filter: :all
|
164
|
+
|
157
165
|
# Returns a reference to the organization this board belongs to.
|
158
166
|
one :organization, path: :organizations, using: :organization_id
|
159
167
|
|
168
|
+
# Returns a list of plugins associated with the board
|
169
|
+
many :plugin_data, path: "pluginData"
|
170
|
+
|
171
|
+
# Returns custom fields activated on this board
|
172
|
+
many :custom_fields, path: "customFields"
|
173
|
+
|
160
174
|
def labels(params = {})
|
161
175
|
# Set the limit to as high as possible given there is no pagination in this API.
|
162
176
|
params[:limit] = 1000 unless params[:limit]
|
data/lib/trello/card.rb
CHANGED
@@ -169,35 +169,29 @@ module Trello
|
|
169
169
|
#
|
170
170
|
# @return [Trello::Card] self
|
171
171
|
def update_fields(fields)
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
attributes[:pos] = fields[SYMBOL_TO_STRING[:pos]] || fields[:pos]
|
186
|
-
attributes[:labels] = (fields[SYMBOL_TO_STRING[:labels]] || []).map { |lbl| Trello::Label.new(lbl) }
|
187
|
-
attributes[:card_labels] = fields[SYMBOL_TO_STRING[:card_labels]] || fields[:card_labels]
|
188
|
-
attributes[:last_activity_date] = Time.iso8601(fields[SYMBOL_TO_STRING[:last_activity_date]]) rescue nil
|
189
|
-
attributes[:cover_image_id] = fields[SYMBOL_TO_STRING[:cover_image_id]]
|
190
|
-
attributes[:badges] = fields[SYMBOL_TO_STRING[:badges]]
|
191
|
-
attributes[:card_members] = fields[SYMBOL_TO_STRING[:card_members]]
|
192
|
-
attributes[:source_card_id] = fields[SYMBOL_TO_STRING[:source_card_id]] || fields[:source_card_id]
|
193
|
-
attributes[:source_card_properties] = fields[SYMBOL_TO_STRING[:source_card_properties]] || fields[:source_card_properties]
|
194
|
-
self
|
172
|
+
%i[
|
173
|
+
name desc due due_complete closed
|
174
|
+
board_id member_ids list_id pos
|
175
|
+
card_labels cover_image_id
|
176
|
+
].each do |key|
|
177
|
+
send("#{key}_will_change!") if fields_has_key?(fields, key)
|
178
|
+
end
|
179
|
+
|
180
|
+
initialize_fields(fields)
|
181
|
+
end
|
182
|
+
|
183
|
+
def initialize(fields = {})
|
184
|
+
initialize_fields(fields)
|
195
185
|
end
|
196
186
|
|
197
187
|
# Returns a reference to the board this card is part of.
|
198
188
|
one :board, path: :boards, using: :board_id
|
189
|
+
|
199
190
|
# Returns a reference to the cover image attachment
|
200
|
-
|
191
|
+
def cover_image(params = {})
|
192
|
+
response = client.get("/cards/#{id}/attachments/#{cover_image_id}", params)
|
193
|
+
CoverImage.from_response(response)
|
194
|
+
end
|
201
195
|
|
202
196
|
# Returns a list of checklists associated with the card.
|
203
197
|
#
|
@@ -209,6 +203,9 @@ module Trello
|
|
209
203
|
# Returns a list of plugins associated with the card
|
210
204
|
many :plugin_data, path: "pluginData"
|
211
205
|
|
206
|
+
# List of custom field values on the card, only the ones that have been set
|
207
|
+
many :custom_field_items, path: 'customFieldItems'
|
208
|
+
|
212
209
|
def check_item_states
|
213
210
|
states = CheckItemState.from_response client.get("/cards/#{self.id}/checkItemStates")
|
214
211
|
MultiAssociation.new(self, states).proxy
|
@@ -221,9 +218,7 @@ module Trello
|
|
221
218
|
#
|
222
219
|
# @return [Array<Trello::Member>]
|
223
220
|
def members
|
224
|
-
members =
|
225
|
-
Member.from_response client.get("/members/#{member_id}")
|
226
|
-
end
|
221
|
+
members = Member.from_response client.get("/cards/#{self.id}/members")
|
227
222
|
MultiAssociation.new(self, members).proxy
|
228
223
|
end
|
229
224
|
|
@@ -269,15 +264,41 @@ module Trello
|
|
269
264
|
#
|
270
265
|
# @raise [Trello::Error] if the card could not be updated.
|
271
266
|
#
|
272
|
-
# @return [
|
273
|
-
# the Trello API.
|
267
|
+
# @return [Trello::Card] updated self
|
274
268
|
def update!
|
275
269
|
@previously_changed = changes
|
276
270
|
# extract only new values to build payload
|
277
271
|
payload = Hash[changes.map { |key, values| [SYMBOL_TO_STRING[key.to_sym].to_sym, values[1]] }]
|
278
|
-
@changed_attributes.clear
|
279
272
|
|
280
|
-
client.put("/cards/#{id}", payload)
|
273
|
+
response = client.put("/cards/#{id}", payload)
|
274
|
+
updated_card = from_response(response)
|
275
|
+
|
276
|
+
@changed_attributes.clear if @changed_attributes.respond_to?(:clear)
|
277
|
+
changes_applied if respond_to?(:changes_applied)
|
278
|
+
|
279
|
+
attributes[:id] = updated_card.id
|
280
|
+
attributes[:short_id] = updated_card.short_id
|
281
|
+
attributes[:name] = updated_card.name
|
282
|
+
attributes[:desc] = updated_card.desc
|
283
|
+
attributes[:due] = updated_card.due
|
284
|
+
attributes[:due_complete] = updated_card.due_complete
|
285
|
+
attributes[:closed] = updated_card.closed
|
286
|
+
attributes[:url] = updated_card.url
|
287
|
+
attributes[:short_url] = updated_card.short_url
|
288
|
+
attributes[:board_id] = updated_card.board_id
|
289
|
+
attributes[:member_ids] = updated_card.member_ids
|
290
|
+
attributes[:list_id] = updated_card.list_id
|
291
|
+
attributes[:pos] = updated_card.pos
|
292
|
+
attributes[:labels] = updated_card.labels
|
293
|
+
attributes[:card_labels] = updated_card.card_labels
|
294
|
+
attributes[:last_activity_date] = updated_card.last_activity_date
|
295
|
+
attributes[:cover_image_id] = updated_card.cover_image_id
|
296
|
+
attributes[:badges] = updated_card.badges
|
297
|
+
attributes[:card_members] = updated_card.card_members
|
298
|
+
attributes[:source_card_id] = updated_card.source_card_id
|
299
|
+
attributes[:source_card_properties] = updated_card.source_card_properties
|
300
|
+
|
301
|
+
self
|
281
302
|
end
|
282
303
|
|
283
304
|
# Delete this card
|
@@ -312,7 +333,7 @@ module Trello
|
|
312
333
|
|
313
334
|
# Is the record valid?
|
314
335
|
def valid?
|
315
|
-
name && list_id
|
336
|
+
!(name && list_id).nil?
|
316
337
|
end
|
317
338
|
|
318
339
|
# Add a comment with the supplied text.
|
@@ -321,10 +342,12 @@ module Trello
|
|
321
342
|
end
|
322
343
|
|
323
344
|
# Add a checklist to this card
|
324
|
-
def add_checklist(checklist)
|
325
|
-
|
326
|
-
|
327
|
-
|
345
|
+
def add_checklist(checklist, name: nil, position: nil)
|
346
|
+
payload = { idChecklistSource: checklist.id }
|
347
|
+
payload[:name] = name if name
|
348
|
+
payload[:pos] = position if position
|
349
|
+
|
350
|
+
client.post("/cards/#{id}/checklists", payload)
|
328
351
|
end
|
329
352
|
|
330
353
|
# create a new checklist and add it to this card
|
@@ -342,6 +365,16 @@ module Trello
|
|
342
365
|
end
|
343
366
|
end
|
344
367
|
|
368
|
+
# Moves this card to the given list no matter which board it is on
|
369
|
+
def move_to_list_on_any_board(list_id)
|
370
|
+
list = List.find(list_id)
|
371
|
+
if board.id == list.board_id
|
372
|
+
move_to_list(list_id)
|
373
|
+
else
|
374
|
+
move_to_board(Board.find(list.board_id), list)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
345
378
|
# Move this card to the given board (and optional list on this board)
|
346
379
|
def move_to_board(new_board, new_list = nil)
|
347
380
|
unless board_id == new_board.id
|
@@ -353,14 +386,14 @@ module Trello
|
|
353
386
|
|
354
387
|
# Add a member to this card
|
355
388
|
def add_member(member)
|
356
|
-
client.post("/cards/#{id}/
|
389
|
+
client.post("/cards/#{id}/idMembers", {
|
357
390
|
value: member.id
|
358
391
|
})
|
359
392
|
end
|
360
393
|
|
361
394
|
# Remove a member from this card
|
362
395
|
def remove_member(member)
|
363
|
-
client.delete("/cards/#{id}/
|
396
|
+
client.delete("/cards/#{id}/idMembers/#{member.id}")
|
364
397
|
end
|
365
398
|
|
366
399
|
# Current authenticated user upvotes a card
|
@@ -452,5 +485,37 @@ module Trello
|
|
452
485
|
def me
|
453
486
|
@me ||= Member.find(:me)
|
454
487
|
end
|
488
|
+
|
489
|
+
def fields_has_key?(fields, key)
|
490
|
+
fields.key?(SYMBOL_TO_STRING[key]) || fields.key?(key)
|
491
|
+
end
|
492
|
+
|
493
|
+
def initialize_fields(fields)
|
494
|
+
attributes[:id] = fields[SYMBOL_TO_STRING[:id]] || attributes[:id]
|
495
|
+
attributes[:short_id] = fields[SYMBOL_TO_STRING[:short_id]] || attributes[:short_id]
|
496
|
+
attributes[:name] = fields[SYMBOL_TO_STRING[:name]] || fields[:name] || attributes[:name]
|
497
|
+
attributes[:desc] = fields[SYMBOL_TO_STRING[:desc]] || fields[:desc] || attributes[:desc]
|
498
|
+
attributes[:due] = Time.iso8601(fields[SYMBOL_TO_STRING[:due]]) rescue nil if fields.has_key?(SYMBOL_TO_STRING[:due])
|
499
|
+
attributes[:due] = fields[:due] if fields.has_key?(:due)
|
500
|
+
attributes[:due_complete] = fields[SYMBOL_TO_STRING[:due_complete]] if fields.has_key?(SYMBOL_TO_STRING[:due_complete])
|
501
|
+
attributes[:due_complete] ||= false
|
502
|
+
attributes[:closed] = fields[SYMBOL_TO_STRING[:closed]] if fields.has_key?(SYMBOL_TO_STRING[:closed])
|
503
|
+
attributes[:url] = fields[SYMBOL_TO_STRING[:url]] || attributes[:url]
|
504
|
+
attributes[:short_url] = fields[SYMBOL_TO_STRING[:short_url]] || attributes[:short_url]
|
505
|
+
attributes[:board_id] = fields[SYMBOL_TO_STRING[:board_id]] || attributes[:board_id]
|
506
|
+
attributes[:member_ids] = fields[SYMBOL_TO_STRING[:member_ids]] || fields[:member_ids] || attributes[:member_ids]
|
507
|
+
attributes[:list_id] = fields[SYMBOL_TO_STRING[:list_id]] || fields[:list_id] || attributes[:list_id]
|
508
|
+
attributes[:pos] = fields[SYMBOL_TO_STRING[:pos]] || fields[:pos] || attributes[:pos]
|
509
|
+
attributes[:labels] = (fields[SYMBOL_TO_STRING[:labels]] || []).map { |lbl| Trello::Label.new(lbl) }.presence || attributes[:labels].presence || []
|
510
|
+
attributes[:card_labels] = fields[SYMBOL_TO_STRING[:card_labels]] || fields[:card_labels] || attributes[:card_labels]
|
511
|
+
attributes[:last_activity_date] = Time.iso8601(fields[SYMBOL_TO_STRING[:last_activity_date]]) rescue nil if fields.has_key?(SYMBOL_TO_STRING[:last_activity_date])
|
512
|
+
attributes[:cover_image_id] = fields[SYMBOL_TO_STRING[:cover_image_id]] || attributes[:cover_image_id]
|
513
|
+
attributes[:badges] = fields[SYMBOL_TO_STRING[:badges]] || attributes[:badges]
|
514
|
+
attributes[:card_members] = fields[SYMBOL_TO_STRING[:card_members]] || attributes[:card_members]
|
515
|
+
attributes[:source_card_id] = fields[SYMBOL_TO_STRING[:source_card_id]] || fields[:source_card_id] || attributes[:source_card_id]
|
516
|
+
attributes[:source_card_properties] = fields[SYMBOL_TO_STRING[:source_card_properties]] || fields[:source_card_properties] || attributes[:source_card_properties]
|
517
|
+
self
|
518
|
+
end
|
519
|
+
|
455
520
|
end
|
456
521
|
end
|