forked from kothar/asana-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
customfields.go
257 lines (200 loc) · 8.19 KB
/
customfields.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
package asana
import (
"encoding/json"
"fmt"
)
type EnumValue struct {
// Read-only. Globally unique ID of the object
ID string `json:"gid,omitempty"`
EnumValueBase
Enabled bool `json:"enabled"`
}
type EnumValueBase struct {
// Read-only. The name of the object.
Name string `json:"name,omitempty"`
Color string `json:"color"`
}
type FieldType string
// FieldTypes for CustomField.Type field
const (
Text FieldType = "text"
Enum FieldType = "enum"
Number FieldType = "number"
)
type LabelPosition string
const (
Prefix LabelPosition = "prefix"
Suffix LabelPosition = "suffix"
)
type Format string
const (
Currency = "currency"
Identifier = "identifier"
Percentage = "percentage"
Custom = "custom"
None = "none"
)
type CustomFieldBase struct {
// ISO 4217 currency code to format this custom field. This will be null
// if the format is not currency.
CurrencyCode string `json:"currency_code,omitempty"`
// This is the string that appears next to the custom field value.
// This will be null if the format is not custom.
CustomLabel string `json:"custom_label,omitempty"`
// Only relevant for custom fields with custom format. This depicts where to place the custom label.
// This will be null if the format is not custom.
CustomLabelPosition LabelPosition `json:"custom_label_position,omitempty"`
// The description of the custom field.
Description string `json:"description,omitempty"`
// Opt In. The description of the custom field.
Enabled *bool `json:"enabled,omitempty"`
// The format of this custom field.
Format Format `json:"format,omitempty"`
// Conditional. This flag describes whether a follower of a task with this
// field should receive inbox notifications from changes to this field.
HasNotificationsEnabled *bool `json:"has_notifications_enabled,omitempty"`
// This flag describes whether this custom field is available to every container
// in the workspace. Before project-specific custom fields, this field was always true.
IsGlobalToWorkspace *bool `json:"is_global_to_workspace,omitempty"`
// Read-only. The name of the object.
Name string `json:"name,omitempty"`
// Only relevant for custom fields of type ‘Number’. This field dictates the number of places after
// the decimal to round to, i.e. 0 is integer values, 1 rounds to the nearest tenth, and so on.
// Must be between 0 and 6, inclusive.
// For percentage format, this may be unintuitive, as a value of 0.25 has a precision of 0, while a
// value of 0.251 has a precision of 1. This is due to 0.25 being displayed as 25%.
// The identifier format will always have a precision of 0.
Precision *int `json:"precision,omitempty"`
// The type of the custom field. Must be one of the given values:
// 'text', 'enum', 'number'
ResourceSubtype FieldType `json:"resource_subtype"`
}
// Custom Fields store the metadata that is used in order to add user-
// specified information to tasks in Asana. Be sure to reference the Custom
// Fields developer documentation for more information about how custom fields
// relate to various resources in Asana.
// Users in Asana can lock custom fields, which will make them read-only when accessed by other users.
// Attempting to edit a locked custom field will return HTTP error code 403 Forbidden.
type CustomField struct {
client *Client
// Read-only. Globally unique ID of the object
ID string `json:"gid,omitempty"`
CustomFieldBase
// Only relevant for custom fields of type ‘Enum’. This array specifies
// the possible values which an enum custom field can adopt.
EnumOptions []*EnumValue `json:"enum_options,omitempty"`
}
type CustomFieldSetting struct {
// Read-only. Globally unique ID of the object
ID string `json:"gid,omitempty"`
CustomField *CustomField `json:"custom_field"`
Project *Project `json:"project,omitempty"`
Important bool `json:"is_important,omitempty"`
}
type AddCustomFieldSettingRequest struct {
CustomField string `json:"custom_field"`
Important bool `json:"is_important,omitempty"`
InsertBefore string `json:"insert_before,omitempty"`
InsertAfter string `json:"insert_after,omitempty"`
}
func (p *Project) AddCustomFieldSetting(request *AddCustomFieldSettingRequest) (*CustomFieldSetting, error) {
p.client.trace("Attach custom field %q to project %q", request.CustomField, p.ID)
// Custom request encoding
m := map[string]interface{}{}
m["custom_field"] = request.CustomField
m["is_important"] = request.Important
if request.InsertAfter == "-" {
m["insert_after"] = nil
} else if request.InsertAfter != "" {
m["insert_after"] = request.InsertAfter
}
if request.InsertBefore == "-" {
m["insert_before"] = nil
} else if request.InsertBefore != "" {
m["insert_before"] = request.InsertBefore
}
result := &CustomFieldSetting{}
err := p.client.post(fmt.Sprintf("/projects/%s/addCustomFieldSetting", p.ID), m, result)
result.CustomField.client = p.client
return result, err
}
func (p *Project) RemoveCustomFieldSetting(customFieldID string) error {
p.client.trace("Remove custom field %q from project %q", customFieldID, p.ID)
// Custom request encoding
m := map[string]interface{}{
"custom_field": customFieldID,
}
err := p.client.post(fmt.Sprintf("/projects/%s/removeCustomFieldSetting", p.ID), m, &json.RawMessage{})
return err
}
type CreateCustomFieldRequest struct {
CustomFieldBase
// Required: The workspace to create a custom field in.
Workspace string `json:"workspace"`
// The discrete values the custom field can assume.
// Required if the custom field is of type ‘enum’.
EnumOptions []*EnumValueBase `json:"enum_options,omitempty"`
}
func (c *Client) CreateCustomField(request *CreateCustomFieldRequest) (*CustomField, error) {
c.trace("Create custom field %q in workspace %s", request.Name, request.Workspace)
result := &CustomField{}
err := c.post("/custom_fields", request, result)
result.client = c
return result, err
}
// When a custom field is associated with a project, tasks in that project can
// carry additional custom field values which represent the value of the field
// on that particular task - for instance, the selected item from an enum type
// custom field. These custom fields will appear as an array in a
// custom_fields property of the task, along with some basic information which
// can be used to associate the custom field value with the custom field
// metadata.
type CustomFieldValue struct {
CustomField
// Custom fields of type text will return a text_value property containing
// the string of text for the field.
TextValue *string `json:"text_value,omitempty"`
// Custom fields of type number will return a number_value property
// containing the number for the field.
NumberValue *float64 `json:"number_value,omitempty"`
// Custom fields of type enum will return an enum_value property
// containing an object that represents the selection of the enum value.
EnumValue *EnumValue `json:"enum_value,omitempty"`
}
// Fetch loads the full details for this CustomField
func (f *CustomField) Fetch(options ...*Options) error {
f.client.trace("Loading details for custom field %q", f.ID)
_, err := f.client.get(fmt.Sprintf("/custom_fields/%s", f.ID), nil, f, options...)
return err
}
// CustomFields returns the compact records for all custom fields in the workspace
func (w *Workspace) CustomFields(options ...*Options) ([]*CustomField, *NextPage, error) {
w.client.trace("Listing custom fields in workspace %s...\n", w.ID)
var result []*CustomField
// Make the request
nextPage, err := w.client.get(fmt.Sprintf("/workspaces/%s/custom_fields", w.ID), nil, &result, options...)
for _, r := range result {
r.client = w.client
}
return result, nextPage, err
}
// AllCustomFields repeatedly pages through all available custom fields in a workspace
func (w *Workspace) AllCustomFields(options ...*Options) ([]*CustomField, error) {
var allCustomFields []*CustomField
nextPage := &NextPage{}
var customFields []*CustomField
var err error
for nextPage != nil {
page := &Options{
Limit: 50,
Offset: nextPage.Offset,
}
allOptions := append([]*Options{page}, options...)
customFields, nextPage, err = w.CustomFields(allOptions...)
if err != nil {
return nil, err
}
allCustomFields = append(allCustomFields, customFields...)
}
return allCustomFields, nil
}