asana 0.8.1 → 0.9.0

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.
@@ -12,6 +12,10 @@ module Asana
12
12
 
13
13
  attr_reader :id
14
14
 
15
+ attr_reader :gid
16
+
17
+ attr_reader :resource_type
18
+
15
19
  attr_reader :user
16
20
 
17
21
  attr_reader :project
@@ -26,24 +30,26 @@ module Asana
26
30
 
27
31
  # Returns the compact project membership records for the project.
28
32
  #
29
- # project - [Id] The project for which to fetch memberships.
33
+ # project - [Gid] The project for which to fetch memberships.
30
34
  # user - [String] If present, the user to filter the memberships to.
31
35
  # per_page - [Integer] the number of records to fetch per page.
32
36
  # options - [Hash] the request I/O options.
33
- def get_many(client, project: required("project"), user: nil, per_page: 20, options: {})
37
+ def find_by_project(client, project: required("project"), user: nil, per_page: 20, options: {})
34
38
  params = { user: user, limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
35
39
  Collection.new(parse(client.get("/projects/#{project}/project_memberships", params: params, options: options)), type: Resource, client: client)
36
40
  end
41
+ alias_method :get_many, :find_by_project
37
42
 
38
43
  # Returns the project membership record.
39
44
  #
40
- # project - [Id] Globally unique identifier for the project membership.
45
+ # id - [Gid] Globally unique identifier for the project membership.
41
46
  #
42
47
  # options - [Hash] the request I/O options.
43
- def get_single(client, project: required("project"), options: {})
48
+ def find_by_id(client, id, options: {})
44
49
 
45
- Resource.new(parse(client.get("/project_memberships/#{project}", options: options)).first, client: client)
50
+ self.new(parse(client.get("/project_memberships/#{id}", options: options)).first, client: client)
46
51
  end
52
+ alias_method :get_single, :find_by_id
47
53
  end
48
54
 
49
55
  end
@@ -14,10 +14,16 @@ module Asana
14
14
 
15
15
  attr_reader :id
16
16
 
17
+ attr_reader :gid
18
+
19
+ attr_reader :resource_type
20
+
17
21
  attr_reader :title
18
22
 
19
23
  attr_reader :text
20
24
 
25
+ attr_reader :html_text
26
+
21
27
  attr_reader :color
22
28
 
23
29
  attr_reader :created_by
@@ -34,21 +40,22 @@ module Asana
34
40
  #
35
41
  # Returns the full record of the newly created project status update.
36
42
  #
37
- # project - [Id] The project on which to create a status update.
43
+ # project - [Gid] The project on which to create a status update.
38
44
  # text - [String] The text of the project status update.
39
45
  #
40
46
  # color - [String] The color to associate with the status update. Must be one of `"red"`, `"yellow"`, or `"green"`.
41
47
  #
42
48
  # options - [Hash] the request I/O options.
43
49
  # data - [Hash] the attributes to post.
44
- def create(client, project: required("project"), text: required("text"), color: required("color"), options: {}, **data)
50
+ def create_in_project(client, project: required("project"), text: required("text"), color: required("color"), options: {}, **data)
45
51
  with_params = data.merge(text: text, color: color).reject { |_,v| v.nil? || Array(v).empty? }
46
52
  Resource.new(parse(client.post("/projects/#{project}/project_statuses", body: with_params, options: options)).first, client: client)
47
53
  end
54
+ alias_method :create, :create_in_project
48
55
 
49
56
  # Returns the compact project status update records for all updates on the project.
50
57
  #
51
- # project - [Id] The project to find status updates for.
58
+ # project - [Gid] The project to find status updates for.
52
59
  # per_page - [Integer] the number of records to fetch per page.
53
60
  # options - [Hash] the request I/O options.
54
61
  def find_by_project(client, project: required("project"), per_page: 20, options: {})
@@ -58,7 +65,7 @@ module Asana
58
65
 
59
66
  # Returns the complete record for a single status update.
60
67
  #
61
- # id - [Id] The project status update to get.
68
+ # id - [Gid] The project status update to get.
62
69
  # options - [Hash] the request I/O options.
63
70
  def find_by_id(client, id, options: {})
64
71
 
@@ -71,7 +78,7 @@ module Asana
71
78
  # Returns an empty data record.
72
79
  def delete()
73
80
 
74
- client.delete("/project_statuses/#{id}") && true
81
+ client.delete("/project_statuses/#{gid}") && true
75
82
  end
76
83
 
77
84
  end
@@ -11,6 +11,10 @@ module Asana
11
11
 
12
12
  attr_reader :id
13
13
 
14
+ attr_reader :gid
15
+
16
+ attr_reader :resource_type
17
+
14
18
  attr_reader :name
15
19
 
16
20
  attr_reader :project
@@ -27,7 +31,7 @@ module Asana
27
31
  #
28
32
  # Returns the full record of the newly created section.
29
33
  #
30
- # project - [Id] The project to create the section in
34
+ # project - [Gid] The project to create the section in
31
35
  # name - [String] The text to be displayed as the section name. This cannot be an empty string.
32
36
  # options - [Hash] the request I/O options.
33
37
  # data - [Hash] the attributes to post.
@@ -38,7 +42,7 @@ module Asana
38
42
 
39
43
  # Returns the compact records for all sections in the specified project.
40
44
  #
41
- # project - [Id] The project to get sections from.
45
+ # project - [Gid] The project to get sections from.
42
46
  # per_page - [Integer] the number of records to fetch per page.
43
47
  # options - [Hash] the request I/O options.
44
48
  def find_by_project(client, project: required("project"), per_page: 20, options: {})
@@ -48,12 +52,28 @@ module Asana
48
52
 
49
53
  # Returns the complete record for a single section.
50
54
  #
51
- # id - [Id] The section to get.
55
+ # id - [Gid] The section to get.
52
56
  # options - [Hash] the request I/O options.
53
57
  def find_by_id(client, id, options: {})
54
58
 
55
59
  self.new(parse(client.get("/sections/#{id}", options: options)).first, client: client)
56
60
  end
61
+
62
+ # Add a task to a specific, existing section. This will remove the task from other sections of the project.
63
+ #
64
+ # The task will be inserted at the top of a section unless an `insert_before` or `insert_after` parameter is declared.
65
+ #
66
+ # This does not work for separators (tasks with the `resource_subtype` of section).
67
+ #
68
+ # task - [Gid] The task to add to this section
69
+ # insert_before - [Gid] Insert the given task immediately before the task specified by this parameter. Cannot be provided together with `insert_after`.
70
+ # insert_after - [Gid] Insert the given task immediately after the task specified by this parameter. Cannot be provided together with `insert_before`.
71
+ # options - [Hash] the request I/O options.
72
+ # data - [Hash] the attributes to post.
73
+ def add_task(client, task: required("task"), insert_before: nil, insert_after: nil, options: {}, **data)
74
+ with_params = data.merge(insert_before: insert_before, insert_after: insert_after).reject { |_,v| v.nil? || Array(v).empty? }
75
+ Task.new(parse(client.post("/sections/#{task}/addTask", body: with_params, options: options)).first, client: client)
76
+ end
57
77
  end
58
78
 
59
79
  # A specific, existing section can be updated by making a PUT request on
@@ -71,7 +91,7 @@ module Asana
71
91
  # data - [Hash] the attributes to post.
72
92
  def update(options: {}, **data)
73
93
 
74
- refresh_with(parse(client.put("/sections/#{id}", body: data, options: options)).first)
94
+ refresh_with(parse(client.put("/sections/#{gid}", body: data, options: options)).first)
75
95
  end
76
96
 
77
97
  # A specific, existing section can be deleted by making a DELETE request
@@ -84,7 +104,7 @@ module Asana
84
104
  # Returns an empty data block.
85
105
  def delete()
86
106
 
87
- client.delete("/sections/#{id}") && true
107
+ client.delete("/sections/#{gid}") && true
88
108
  end
89
109
 
90
110
  # Move sections relative to each other in a board view. One of
@@ -96,9 +116,9 @@ module Asana
96
116
  #
97
117
  # Returns an empty data block.
98
118
  #
99
- # project - [Id] The project in which to reorder the given section
100
- # before_section - [Id] Insert the given section immediately before the section specified by this parameter.
101
- # after_section - [Id] Insert the given section immediately after the section specified by this parameter.
119
+ # project - [Gid] The project in which to reorder the given section
120
+ # before_section - [Gid] Insert the given section immediately before the section specified by this parameter.
121
+ # after_section - [Gid] Insert the given section immediately after the section specified by this parameter.
102
122
  # options - [Hash] the request I/O options.
103
123
  # data - [Hash] the attributes to post.
104
124
  def insert_in_project(project: required("project"), before_section: nil, after_section: nil, options: {}, **data)
@@ -7,30 +7,26 @@ module Asana
7
7
  # system. Stories are generated by the system whenever users take actions such
8
8
  # as creating or assigning tasks, or moving tasks between projects. _Comments_
9
9
  # are also a form of user-generated story.
10
- #
11
- # Stories are a form of history in the system, and as such they are read-only.
12
- # Once generated, it is not possible to modify a story.
13
10
  class Story < Resource
14
11
 
15
12
 
16
13
  attr_reader :id
17
14
 
18
- attr_reader :created_at
15
+ attr_reader :gid
19
16
 
20
- attr_reader :created_by
17
+ attr_reader :resource_type
21
18
 
22
- # DEPRECATED: prefer "liked"
23
- attr_reader :hearted
19
+ attr_reader :resource_subtype
24
20
 
25
- # DEPRECATED: prefer "likes"
26
- attr_reader :hearts
21
+ attr_reader :created_at
27
22
 
28
- # DEPRECATED: prefer "num_likes"
29
- attr_reader :num_hearts
23
+ attr_reader :created_by
30
24
 
31
25
  attr_reader :liked
26
+ alias_method :hearted, :liked
32
27
 
33
28
  attr_reader :likes
29
+ alias_method :hearts, :likes
34
30
 
35
31
  attr_reader :num_likes
36
32
 
@@ -56,7 +52,7 @@ module Asana
56
52
 
57
53
  # Returns the compact records for all stories on the task.
58
54
  #
59
- # task - [Id] Globally unique identifier for the task.
55
+ # task - [Gid] Globally unique identifier for the task.
60
56
  #
61
57
  # per_page - [Integer] the number of records to fetch per page.
62
58
  # options - [Hash] the request I/O options.
@@ -67,7 +63,7 @@ module Asana
67
63
 
68
64
  # Returns the full record for a single story.
69
65
  #
70
- # id - [Id] Globally unique identifier for the story.
66
+ # id - [Gid] Globally unique identifier for the story.
71
67
  #
72
68
  # options - [Hash] the request I/O options.
73
69
  def find_by_id(client, id, options: {})
@@ -104,13 +100,13 @@ module Asana
104
100
  # data - [Hash] the attributes to post.
105
101
  def update(text: nil, html_text: nil, is_pinned: nil, options: {}, **data)
106
102
  with_params = data.merge(text: text, html_text: html_text, is_pinned: is_pinned).reject { |_,v| v.nil? || Array(v).empty? }
107
- refresh_with(parse(client.put("/stories/#{id}", body: with_params, options: options)).first)
103
+ refresh_with(parse(client.put("/stories/#{gid}", body: with_params, options: options)).first)
108
104
  end
109
105
 
110
106
  # Deletes a story. A user can only delete stories they have created. Returns an empty data record.
111
107
  def delete()
112
108
 
113
- client.delete("/stories/#{id}") && true
109
+ client.delete("/stories/#{gid}") && true
114
110
  end
115
111
 
116
112
  end
@@ -15,6 +15,10 @@ module Asana
15
15
 
16
16
  attr_reader :id
17
17
 
18
+ attr_reader :gid
19
+
20
+ attr_reader :resource_type
21
+
18
22
  attr_reader :created_at
19
23
 
20
24
  attr_reader :followers
@@ -40,7 +44,7 @@ module Asana
40
44
  #
41
45
  # Returns the full record of the newly created tag.
42
46
  #
43
- # workspace - [Id] The workspace or organization to create the tag in.
47
+ # workspace - [Gid] The workspace or organization to create the tag in.
44
48
  # options - [Hash] the request I/O options.
45
49
  # data - [Hash] the attributes to post.
46
50
  def create(client, workspace: required("workspace"), options: {}, **data)
@@ -57,7 +61,7 @@ module Asana
57
61
  #
58
62
  # Returns the full record of the newly created tag.
59
63
  #
60
- # workspace - [Id] The workspace or organization to create the tag in.
64
+ # workspace - [Gid] The workspace or organization to create the tag in.
61
65
  # options - [Hash] the request I/O options.
62
66
  # data - [Hash] the attributes to post.
63
67
  def create_in_workspace(client, workspace: required("workspace"), options: {}, **data)
@@ -67,7 +71,7 @@ module Asana
67
71
 
68
72
  # Returns the complete tag record for a single tag.
69
73
  #
70
- # id - [Id] The tag to get.
74
+ # id - [Gid] The tag to get.
71
75
  # options - [Hash] the request I/O options.
72
76
  def find_by_id(client, id, options: {})
73
77
 
@@ -77,8 +81,8 @@ module Asana
77
81
  # Returns the compact tag records for some filtered set of tags.
78
82
  # Use one or more of the parameters provided to filter the tags returned.
79
83
  #
80
- # workspace - [Id] The workspace or organization to filter tags on.
81
- # team - [Id] The team to filter tags on.
84
+ # workspace - [Gid] The workspace or organization to filter tags on.
85
+ # team - [Gid] The team to filter tags on.
82
86
  # archived - [Boolean] Only return tags whose `archived` field takes on the value of
83
87
  # this parameter.
84
88
  #
@@ -91,7 +95,7 @@ module Asana
91
95
 
92
96
  # Returns the compact tag records for all tags in the workspace.
93
97
  #
94
- # workspace - [Id] The workspace or organization to find tags in.
98
+ # workspace - [Gid] The workspace or organization to find tags in.
95
99
  # per_page - [Integer] the number of records to fetch per page.
96
100
  # options - [Hash] the request I/O options.
97
101
  def find_by_workspace(client, workspace: required("workspace"), per_page: 20, options: {})
@@ -113,7 +117,7 @@ module Asana
113
117
  # data - [Hash] the attributes to post.
114
118
  def update(options: {}, **data)
115
119
 
116
- refresh_with(parse(client.put("/tags/#{id}", body: data, options: options)).first)
120
+ refresh_with(parse(client.put("/tags/#{gid}", body: data, options: options)).first)
117
121
  end
118
122
 
119
123
  # A specific, existing tag can be deleted by making a DELETE request
@@ -122,7 +126,7 @@ module Asana
122
126
  # Returns an empty data record.
123
127
  def delete()
124
128
 
125
- client.delete("/tags/#{id}") && true
129
+ client.delete("/tags/#{gid}") && true
126
130
  end
127
131
 
128
132
  # Returns the compact task records for all tasks with the given tag.
@@ -132,7 +136,7 @@ module Asana
132
136
  # options - [Hash] the request I/O options.
133
137
  def get_tasks_with_tag(per_page: 20, options: {})
134
138
  params = { limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
135
- Collection.new(parse(client.get("/tags/#{id}/tasks", params: params, options: options)), type: Task, client: client)
139
+ Collection.new(parse(client.get("/tags/#{gid}/tasks", params: params, options: options)), type: Task, client: client)
136
140
  end
137
141
 
138
142
  end
@@ -16,6 +16,12 @@ module Asana
16
16
 
17
17
  attr_reader :id
18
18
 
19
+ attr_reader :gid
20
+
21
+ attr_reader :resource_type
22
+
23
+ attr_reader :resource_subtype
24
+
19
25
  attr_reader :assignee
20
26
 
21
27
  attr_reader :assignee_status
@@ -40,37 +46,34 @@ module Asana
40
46
 
41
47
  attr_reader :followers
42
48
 
43
- # DEPRECATED: prefer "liked"
44
- attr_reader :hearted
45
-
46
- # DEPRECATED: prefer "likes"
47
- attr_reader :hearts
49
+ attr_reader :is_rendered_as_separator
48
50
 
49
51
  attr_reader :liked
50
52
 
51
53
  attr_reader :likes
52
54
 
55
+ attr_reader :memberships
56
+
53
57
  attr_reader :modified_at
54
58
 
55
59
  attr_reader :name
56
60
 
57
61
  attr_reader :notes
58
62
 
59
- # DEPRECATED: prefer "num_likes"
60
- attr_reader :num_hearts
63
+ attr_reader :html_notes
61
64
 
62
65
  attr_reader :num_likes
63
66
 
64
- attr_reader :projects
67
+ attr_reader :num_subtasks
65
68
 
66
69
  attr_reader :parent
67
70
 
71
+ attr_reader :projects
72
+
68
73
  attr_reader :start_on
69
74
 
70
75
  attr_reader :workspace
71
76
 
72
- attr_reader :memberships
73
-
74
77
  attr_reader :tags
75
78
 
76
79
  class << self
@@ -90,7 +93,7 @@ module Asana
90
93
  # `projects` can be a comma separated list of projects, or just a single
91
94
  # project the task should belong to.
92
95
  #
93
- # workspace - [Id] The workspace to create a task in.
96
+ # workspace - [Gid] The workspace to create a task in.
94
97
  # options - [Hash] the request I/O options.
95
98
  # data - [Hash] the attributes to post.
96
99
  def create(client, workspace: nil, options: {}, **data)
@@ -106,7 +109,7 @@ module Asana
106
109
  # workspace cannot be changed once set. The workspace need not be set
107
110
  # explicitly if you specify a `project` or a `parent` task instead.
108
111
  #
109
- # workspace - [Id] The workspace to create a task in.
112
+ # workspace - [Gid] The workspace to create a task in.
110
113
  # options - [Hash] the request I/O options.
111
114
  # data - [Hash] the attributes to post.
112
115
  def create_in_workspace(client, workspace: required("workspace"), options: {}, **data)
@@ -116,7 +119,7 @@ module Asana
116
119
 
117
120
  # Returns the complete task record for a single task.
118
121
  #
119
- # id - [Id] The task to get.
122
+ # id - [Gid] The task to get.
120
123
  # options - [Hash] the request I/O options.
121
124
  def find_by_id(client, id, options: {})
122
125
 
@@ -126,17 +129,17 @@ module Asana
126
129
  # Returns the compact task records for all tasks within the given project,
127
130
  # ordered by their priority within the project.
128
131
  #
129
- # projectId - [Id] The project in which to search for tasks.
132
+ # project - [Gid] The project in which to search for tasks.
130
133
  # per_page - [Integer] the number of records to fetch per page.
131
134
  # options - [Hash] the request I/O options.
132
- def find_by_project(client, projectId: required("projectId"), per_page: 20, options: {})
135
+ def find_by_project(client, project: nil, projectId: nil, per_page: 20, options: {})
133
136
  params = { limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
134
- Collection.new(parse(client.get("/projects/#{projectId}/tasks", params: params, options: options)), type: self, client: client)
137
+ Collection.new(parse(client.get("/projects/#{project != nil ? project : projectId}/tasks", params: params, options: options)), type: self, client: client)
135
138
  end
136
139
 
137
140
  # Returns the compact task records for all tasks with the given tag.
138
141
  #
139
- # tag - [Id] The tag in which to search for tasks.
142
+ # tag - [Gid] The tag in which to search for tasks.
140
143
  # per_page - [Integer] the number of records to fetch per page.
141
144
  # options - [Hash] the request I/O options.
142
145
  def find_by_tag(client, tag: required("tag"), per_page: 20, options: {})
@@ -146,7 +149,7 @@ module Asana
146
149
 
147
150
  # <b>Board view only:</b> Returns the compact section records for all tasks within the given section.
148
151
  #
149
- # section - [Id] The section in which to search for tasks.
152
+ # section - [Gid] The section in which to search for tasks.
150
153
  # per_page - [Integer] the number of records to fetch per page.
151
154
  # options - [Hash] the request I/O options.
152
155
  def find_by_section(client, section: required("section"), per_page: 20, options: {})
@@ -154,14 +157,46 @@ module Asana
154
157
  Collection.new(parse(client.get("/sections/#{section}/tasks", params: params, options: options)), type: self, client: client)
155
158
  end
156
159
 
160
+ # Returns the compact list of tasks in a user's My Tasks list. The returned
161
+ # tasks will be in order within each assignee status group of `Inbox`,
162
+ # `Today`, and `Upcoming`.
163
+ #
164
+ # **Note:** tasks in `Later` have a different ordering in the Asana web app
165
+ # than the other assignee status groups; this endpoint will still return
166
+ # them in list order in `Later` (differently than they show up in Asana,
167
+ # but the same order as in Asana's mobile apps).
168
+ #
169
+ # **Note:** Access control is enforced for this endpoint as with all Asana
170
+ # API endpoints, meaning a user's private tasks will be filtered out if the
171
+ # API-authenticated user does not have access to them.
172
+ #
173
+ # **Note:** Both complete and incomplete tasks are returned by default
174
+ # unless they are filtered out (for example, setting `completed_since=now`
175
+ # will return only incomplete tasks, which is the default view for "My
176
+ # Tasks" in Asana.)
177
+ #
178
+ # user_task_list - [Gid] The user task list in which to search for tasks.
179
+ # completed_since - [String] Only return tasks that are either incomplete or that have been
180
+ # completed since this time.
181
+ #
182
+ # per_page - [Integer] the number of records to fetch per page.
183
+ # options - [Hash] the request I/O options.
184
+ def find_by_user_task_list(client, user_task_list: required("user_task_list"), completed_since: nil, per_page: 20, options: {})
185
+ params = { completed_since: completed_since, limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
186
+ Collection.new(parse(client.get("/user_task_lists/#{user_task_list}/tasks", params: params, options: options)), type: self, client: client)
187
+ end
188
+
157
189
  # Returns the compact task records for some filtered set of tasks. Use one
158
190
  # or more of the parameters provided to filter the tasks returned. You must
159
- # specify a `project` or `tag` if you do not specify `assignee` and `workspace`.
191
+ # specify a `project`, `section`, `tag`, or `user_task_list` if you do not
192
+ # specify `assignee` and `workspace`.
160
193
  #
161
194
  # assignee - [String] The assignee to filter tasks on.
162
- # project - [Id] The project to filter tasks on.
163
- # section - [Id] The section to filter tasks on.
164
- # workspace - [Id] The workspace or organization to filter tasks on.
195
+ # workspace - [Gid] The workspace or organization to filter tasks on.
196
+ # project - [Gid] The project to filter tasks on.
197
+ # section - [Gid] The section to filter tasks on.
198
+ # tag - [Gid] The tag to filter tasks on.
199
+ # user_task_list - [Gid] The user task list to filter tasks on.
165
200
  # completed_since - [String] Only return tasks that are either incomplete or that have been
166
201
  # completed since this time.
167
202
  #
@@ -173,30 +208,33 @@ module Asana
173
208
  #
174
209
  # If you specify `assignee`, you must also specify the `workspace` to filter on.
175
210
  #
176
- # Currently, this is only supported in board views.
177
- #
178
211
  # If you specify `workspace`, you must also specify the `assignee` to filter on.
179
212
  #
213
+ # Currently, this is only supported in board views.
214
+ #
180
215
  # A task is considered "modified" if any of its properties change,
181
216
  # or associations between it and other objects are modified (e.g.
182
217
  # a task being added to a project). A task is not considered modified
183
218
  # just because another object it is associated with (e.g. a subtask)
184
219
  # is modified. Actions that count as modifying the task include
185
220
  # assigning, renaming, completing, and adding stories.
186
- def find_all(client, assignee: nil, project: nil, section: nil, workspace: nil, completed_since: nil, modified_since: nil, per_page: 20, options: {})
187
- params = { assignee: assignee, project: project, section: section, workspace: workspace, completed_since: completed_since, modified_since: modified_since, limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
221
+ def find_all(client, assignee: nil, workspace: nil, project: nil, section: nil, tag: nil, user_task_list: nil, completed_since: nil, modified_since: nil, per_page: 20, options: {})
222
+ params = { assignee: assignee, workspace: workspace, project: project, section: section, tag: tag, user_task_list: user_task_list, completed_since: completed_since, modified_since: modified_since, limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
188
223
  Collection.new(parse(client.get("/tasks", params: params, options: options)), type: self, client: client)
189
224
  end
190
225
 
191
226
  # The search endpoint allows you to build complex queries to find and fetch exactly the data you need from Asana. For a more comprehensive description of all the query parameters and limitations of this endpoint, see our [long-form documentation](/developers/documentation/getting-started/search-api) for this feature.
192
227
  #
193
- # workspace - [Id] The workspace or organization in which to search for tasks.
228
+ # workspace - [Gid] The workspace or organization in which to search for tasks.
229
+ # resource_subtype - [Enum] Filters results by the task's resource_subtype.
230
+ #
194
231
  # per_page - [Integer] the number of records to fetch per page.
195
232
  # options - [Hash] the request I/O options.
196
- def search(client, workspace: required("workspace"), per_page: 20, options: {})
197
- params = { limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
233
+ def search_in_workspace(client, workspace: required("workspace"), resource_subtype: nil, per_page: 20, options: {})
234
+ params = { resource_subtype: resource_subtype, limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
198
235
  Collection.new(parse(client.get("/workspaces/#{workspace}/tasks/search", params: params, options: options)), type: Resource, client: client)
199
236
  end
237
+ alias_method :search, :search_in_workspace
200
238
  end
201
239
 
202
240
  # A specific, existing task can be updated by making a PUT request on the
@@ -213,7 +251,7 @@ module Asana
213
251
  # data - [Hash] the attributes to post.
214
252
  def update(options: {}, **data)
215
253
 
216
- refresh_with(parse(client.put("/tasks/#{id}", body: data, options: options)).first)
254
+ refresh_with(parse(client.put("/tasks/#{gid}", body: data, options: options)).first)
217
255
  end
218
256
 
219
257
  # A specific, existing task can be deleted by making a DELETE request on the
@@ -224,7 +262,19 @@ module Asana
224
262
  # Returns an empty data record.
225
263
  def delete()
226
264
 
227
- client.delete("/tasks/#{id}") && true
265
+ client.delete("/tasks/#{gid}") && true
266
+ end
267
+
268
+ # Creates and returns a job that will asynchronously handle the duplication.
269
+ #
270
+ # name - [String] The name of the new task.
271
+ # include - [Array] The fields that will be duplicated to the new task.
272
+ #
273
+ # options - [Hash] the request I/O options.
274
+ # data - [Hash] the attributes to post.
275
+ def duplicate_task(name: required("name"), include: nil, options: {}, **data)
276
+ with_params = data.merge(name: name, include: include).reject { |_,v| v.nil? || Array(v).empty? }
277
+ Resource.new(parse(client.post("/tasks/#{gid}/duplicate", body: with_params, options: options)).first, client: client)
228
278
  end
229
279
 
230
280
  # Returns the compact representations of all of the dependencies of a task.
@@ -232,7 +282,7 @@ module Asana
232
282
  # options - [Hash] the request I/O options.
233
283
  def dependencies(options: {})
234
284
 
235
- Resource.new(parse(client.get("/tasks/#{id}/dependencies", options: options)).first, client: client)
285
+ Collection.new(parse(client.get("/tasks/#{gid}/dependencies", options: options)), type: self.class, client: client)
236
286
  end
237
287
 
238
288
  # Returns the compact representations of all of the dependents of a task.
@@ -240,7 +290,7 @@ module Asana
240
290
  # options - [Hash] the request I/O options.
241
291
  def dependents(options: {})
242
292
 
243
- Resource.new(parse(client.get("/tasks/#{id}/dependents", options: options)).first, client: client)
293
+ Collection.new(parse(client.get("/tasks/#{gid}/dependents", options: options)), type: self.class, client: client)
244
294
  end
245
295
 
246
296
  # Marks a set of tasks as dependencies of this task, if they are not
@@ -251,7 +301,7 @@ module Asana
251
301
  # data - [Hash] the attributes to post.
252
302
  def add_dependencies(dependencies: required("dependencies"), options: {}, **data)
253
303
  with_params = data.merge(dependencies: dependencies).reject { |_,v| v.nil? || Array(v).empty? }
254
- Resource.new(parse(client.post("/tasks/#{id}/addDependencies", body: with_params, options: options)).first, client: client)
304
+ Collection.new(parse(client.post("/tasks/#{gid}/addDependencies", body: with_params, options: options)), type: self.class, client: client)
255
305
  end
256
306
 
257
307
  # Marks a set of tasks as dependents of this task, if they are not already
@@ -262,7 +312,7 @@ module Asana
262
312
  # data - [Hash] the attributes to post.
263
313
  def add_dependents(dependents: required("dependents"), options: {}, **data)
264
314
  with_params = data.merge(dependents: dependents).reject { |_,v| v.nil? || Array(v).empty? }
265
- Resource.new(parse(client.post("/tasks/#{id}/addDependents", body: with_params, options: options)).first, client: client)
315
+ Collection.new(parse(client.post("/tasks/#{gid}/addDependents", body: with_params, options: options)), type: self.class, client: client)
266
316
  end
267
317
 
268
318
  # Unlinks a set of dependencies from this task.
@@ -272,7 +322,7 @@ module Asana
272
322
  # data - [Hash] the attributes to post.
273
323
  def remove_dependencies(dependencies: required("dependencies"), options: {}, **data)
274
324
  with_params = data.merge(dependencies: dependencies).reject { |_,v| v.nil? || Array(v).empty? }
275
- Resource.new(parse(client.post("/tasks/#{id}/removeDependencies", body: with_params, options: options)).first, client: client)
325
+ Collection.new(parse(client.post("/tasks/#{gid}/removeDependencies", body: with_params, options: options)), type: self.class, client: client)
276
326
  end
277
327
 
278
328
  # Unlinks a set of dependents from this task.
@@ -282,7 +332,7 @@ module Asana
282
332
  # data - [Hash] the attributes to post.
283
333
  def remove_dependents(dependents: required("dependents"), options: {}, **data)
284
334
  with_params = data.merge(dependents: dependents).reject { |_,v| v.nil? || Array(v).empty? }
285
- Resource.new(parse(client.post("/tasks/#{id}/removeDependents", body: with_params, options: options)).first, client: client)
335
+ Collection.new(parse(client.post("/tasks/#{gid}/removeDependents", body: with_params, options: options)), type: self.class, client: client)
286
336
  end
287
337
 
288
338
  # Adds each of the specified followers to the task, if they are not already
@@ -293,7 +343,7 @@ module Asana
293
343
  # data - [Hash] the attributes to post.
294
344
  def add_followers(followers: required("followers"), options: {}, **data)
295
345
  with_params = data.merge(followers: followers).reject { |_,v| v.nil? || Array(v).empty? }
296
- refresh_with(parse(client.post("/tasks/#{id}/addFollowers", body: with_params, options: options)).first)
346
+ refresh_with(parse(client.post("/tasks/#{gid}/addFollowers", body: with_params, options: options)).first)
297
347
  end
298
348
 
299
349
  # Removes each of the specified followers from the task if they are
@@ -304,7 +354,7 @@ module Asana
304
354
  # data - [Hash] the attributes to post.
305
355
  def remove_followers(followers: required("followers"), options: {}, **data)
306
356
  with_params = data.merge(followers: followers).reject { |_,v| v.nil? || Array(v).empty? }
307
- refresh_with(parse(client.post("/tasks/#{id}/removeFollowers", body: with_params, options: options)).first)
357
+ refresh_with(parse(client.post("/tasks/#{gid}/removeFollowers", body: with_params, options: options)).first)
308
358
  end
309
359
 
310
360
  # Returns a compact representation of all of the projects the task is in.
@@ -313,7 +363,7 @@ module Asana
313
363
  # options - [Hash] the request I/O options.
314
364
  def projects(per_page: 20, options: {})
315
365
  params = { limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
316
- Collection.new(parse(client.get("/tasks/#{id}/projects", params: params, options: options)), type: Project, client: client)
366
+ Collection.new(parse(client.get("/tasks/#{gid}/projects", params: params, options: options)), type: Project, client: client)
317
367
  end
318
368
 
319
369
  # Adds the task to the specified project, in the optional location
@@ -331,21 +381,21 @@ module Asana
331
381
  #
332
382
  # Returns an empty data block.
333
383
  #
334
- # project - [Id] The project to add the task to.
335
- # insert_after - [Id] A task in the project to insert the task after, or `null` to
384
+ # project - [Gid] The project to add the task to.
385
+ # insert_after - [Gid] A task in the project to insert the task after, or `null` to
336
386
  # insert at the beginning of the list.
337
387
  #
338
- # insert_before - [Id] A task in the project to insert the task before, or `null` to
388
+ # insert_before - [Gid] A task in the project to insert the task before, or `null` to
339
389
  # insert at the end of the list.
340
390
  #
341
- # section - [Id] A section in the project to insert the task into. The task will be
391
+ # section - [Gid] A section in the project to insert the task into. The task will be
342
392
  # inserted at the bottom of the section.
343
393
  #
344
394
  # options - [Hash] the request I/O options.
345
395
  # data - [Hash] the attributes to post.
346
396
  def add_project(project: required("project"), insert_after: nil, insert_before: nil, section: nil, options: {}, **data)
347
397
  with_params = data.merge(project: project, insert_after: insert_after, insert_before: insert_before, section: section).reject { |_,v| v.nil? || Array(v).empty? }
348
- client.post("/tasks/#{id}/addProject", body: with_params, options: options) && true
398
+ client.post("/tasks/#{gid}/addProject", body: with_params, options: options) && true
349
399
  end
350
400
 
351
401
  # Removes the task from the specified project. The task will still exist
@@ -353,12 +403,12 @@ module Asana
353
403
  #
354
404
  # Returns an empty data block.
355
405
  #
356
- # project - [Id] The project to remove the task from.
406
+ # project - [Gid] The project to remove the task from.
357
407
  # options - [Hash] the request I/O options.
358
408
  # data - [Hash] the attributes to post.
359
409
  def remove_project(project: required("project"), options: {}, **data)
360
410
  with_params = data.merge(project: project).reject { |_,v| v.nil? || Array(v).empty? }
361
- client.post("/tasks/#{id}/removeProject", body: with_params, options: options) && true
411
+ client.post("/tasks/#{gid}/removeProject", body: with_params, options: options) && true
362
412
  end
363
413
 
364
414
  # Returns a compact representation of all of the tags the task has.
@@ -367,27 +417,27 @@ module Asana
367
417
  # options - [Hash] the request I/O options.
368
418
  def tags(per_page: 20, options: {})
369
419
  params = { limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
370
- Collection.new(parse(client.get("/tasks/#{id}/tags", params: params, options: options)), type: Tag, client: client)
420
+ Collection.new(parse(client.get("/tasks/#{gid}/tags", params: params, options: options)), type: Tag, client: client)
371
421
  end
372
422
 
373
423
  # Adds a tag to a task. Returns an empty data block.
374
424
  #
375
- # tag - [Id] The tag to add to the task.
425
+ # tag - [Gid] The tag to add to the task.
376
426
  # options - [Hash] the request I/O options.
377
427
  # data - [Hash] the attributes to post.
378
428
  def add_tag(tag: required("tag"), options: {}, **data)
379
429
  with_params = data.merge(tag: tag).reject { |_,v| v.nil? || Array(v).empty? }
380
- client.post("/tasks/#{id}/addTag", body: with_params, options: options) && true
430
+ client.post("/tasks/#{gid}/addTag", body: with_params, options: options) && true
381
431
  end
382
432
 
383
433
  # Removes a tag from the task. Returns an empty data block.
384
434
  #
385
- # tag - [Id] The tag to remove from the task.
435
+ # tag - [Gid] The tag to remove from the task.
386
436
  # options - [Hash] the request I/O options.
387
437
  # data - [Hash] the attributes to post.
388
438
  def remove_tag(tag: required("tag"), options: {}, **data)
389
439
  with_params = data.merge(tag: tag).reject { |_,v| v.nil? || Array(v).empty? }
390
- client.post("/tasks/#{id}/removeTag", body: with_params, options: options) && true
440
+ client.post("/tasks/#{gid}/removeTag", body: with_params, options: options) && true
391
441
  end
392
442
 
393
443
  # Returns a compact representation of all of the subtasks of a task.
@@ -396,7 +446,7 @@ module Asana
396
446
  # options - [Hash] the request I/O options.
397
447
  def subtasks(per_page: 20, options: {})
398
448
  params = { limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
399
- Collection.new(parse(client.get("/tasks/#{id}/subtasks", params: params, options: options)), type: self.class, client: client)
449
+ Collection.new(parse(client.get("/tasks/#{gid}/subtasks", params: params, options: options)), type: self.class, client: client)
400
450
  end
401
451
 
402
452
  # Creates a new subtask and adds it to the parent task. Returns the full record
@@ -406,7 +456,7 @@ module Asana
406
456
  # data - [Hash] the attributes to post.
407
457
  def add_subtask(options: {}, **data)
408
458
 
409
- self.class.new(parse(client.post("/tasks/#{id}/subtasks", body: data, options: options)).first, client: client)
459
+ self.class.new(parse(client.post("/tasks/#{gid}/subtasks", body: data, options: options)).first, client: client)
410
460
  end
411
461
 
412
462
  # Changes the parent of a task. Each task may only be a subtask of a single
@@ -414,18 +464,18 @@ module Asana
414
464
  # at most one of those two options can be specified, and they must already be subtasks
415
465
  # of the parent.
416
466
  #
417
- # parent - [Id] The new parent of the task, or `null` for no parent.
418
- # insert_after - [Id] A subtask of the parent to insert the task after, or `null` to
467
+ # parent - [Gid] The new parent of the task, or `null` for no parent.
468
+ # insert_after - [Gid] A subtask of the parent to insert the task after, or `null` to
419
469
  # insert at the beginning of the list.
420
470
  #
421
- # insert_before - [Id] A subtask of the parent to insert the task before, or `null` to
471
+ # insert_before - [Gid] A subtask of the parent to insert the task before, or `null` to
422
472
  # insert at the end of the list.
423
473
  #
424
474
  # options - [Hash] the request I/O options.
425
475
  # data - [Hash] the attributes to post.
426
476
  def set_parent(parent: required("parent"), insert_after: nil, insert_before: nil, options: {}, **data)
427
477
  with_params = data.merge(parent: parent, insert_after: insert_after, insert_before: insert_before).reject { |_,v| v.nil? || Array(v).empty? }
428
- client.post("/tasks/#{id}/setParent", body: with_params, options: options) && true
478
+ client.post("/tasks/#{gid}/setParent", body: with_params, options: options) && true
429
479
  end
430
480
 
431
481
  # Returns a compact representation of all of the stories on the task.
@@ -434,7 +484,7 @@ module Asana
434
484
  # options - [Hash] the request I/O options.
435
485
  def stories(per_page: 20, options: {})
436
486
  params = { limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
437
- Collection.new(parse(client.get("/tasks/#{id}/stories", params: params, options: options)), type: Story, client: client)
487
+ Collection.new(parse(client.get("/tasks/#{gid}/stories", params: params, options: options)), type: Story, client: client)
438
488
  end
439
489
 
440
490
  # Adds a comment to a task. The comment will be authored by the
@@ -448,7 +498,32 @@ module Asana
448
498
  # data - [Hash] the attributes to post.
449
499
  def add_comment(text: required("text"), options: {}, **data)
450
500
  with_params = data.merge(text: text).reject { |_,v| v.nil? || Array(v).empty? }
451
- Story.new(parse(client.post("/tasks/#{id}/stories", body: with_params, options: options)).first, client: client)
501
+ Story.new(parse(client.post("/tasks/#{gid}/stories", body: with_params, options: options)).first, client: client)
502
+ end
503
+
504
+ # Insert or reorder tasks in a user's My Tasks list. If the task was not
505
+ # assigned to the owner of the user task list it will be reassigned when
506
+ # this endpoint is called. If neither `insert_before` nor `insert_after`
507
+ # are provided the task will be inserted at the top of the assignee's
508
+ # inbox.
509
+ #
510
+ # Returns an empty data block.
511
+ #
512
+ # user_task_list - [Gid] Globally unique identifier for the user task list.
513
+ #
514
+ # insert_before - [Gid] Insert the task before the task specified by this field. The inserted
515
+ # task will inherit the `assignee_status` of this task. `insert_before`
516
+ # and `insert_after` parameters cannot both be specified.
517
+ #
518
+ # insert_after - [Gid] Insert the task after the task specified by this field. The inserted
519
+ # task will inherit the `assignee_status` of this task. `insert_before`
520
+ # and `insert_after` parameters cannot both be specified.
521
+ #
522
+ # options - [Hash] the request I/O options.
523
+ # data - [Hash] the attributes to post.
524
+ def insert_in_user_task_list(user_task_list: required("user_task_list"), insert_before: nil, insert_after: nil, options: {}, **data)
525
+ with_params = data.merge(insert_before: insert_before, insert_after: insert_after).reject { |_,v| v.nil? || Array(v).empty? }
526
+ client.post("/user_task_lists/#{user_task_list}/tasks/insert", body: with_params, options: options) && true
452
527
  end
453
528
 
454
529
  end