monday_ruby 1.1.0 → 1.2.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.
- checksums.yaml +4 -4
- data/.env +1 -1
- data/.rubocop.yml +2 -1
- data/CHANGELOG.md +14 -0
- data/CONTRIBUTING.md +104 -0
- data/README.md +146 -142
- data/docs/.vitepress/config.mjs +255 -0
- data/docs/.vitepress/theme/index.js +4 -0
- data/docs/.vitepress/theme/style.css +43 -0
- data/docs/README.md +80 -0
- data/docs/explanation/architecture.md +507 -0
- data/docs/explanation/best-practices/errors.md +478 -0
- data/docs/explanation/best-practices/performance.md +1084 -0
- data/docs/explanation/best-practices/rate-limiting.md +630 -0
- data/docs/explanation/best-practices/testing.md +820 -0
- data/docs/explanation/column-values.md +857 -0
- data/docs/explanation/design.md +795 -0
- data/docs/explanation/graphql.md +356 -0
- data/docs/explanation/migration/v1.md +808 -0
- data/docs/explanation/pagination.md +447 -0
- data/docs/guides/advanced/batch.md +1274 -0
- data/docs/guides/advanced/complex-queries.md +1114 -0
- data/docs/guides/advanced/errors.md +818 -0
- data/docs/guides/advanced/pagination.md +934 -0
- data/docs/guides/advanced/rate-limiting.md +981 -0
- data/docs/guides/authentication.md +286 -0
- data/docs/guides/boards/create.md +386 -0
- data/docs/guides/boards/delete.md +405 -0
- data/docs/guides/boards/duplicate.md +511 -0
- data/docs/guides/boards/query.md +530 -0
- data/docs/guides/boards/update.md +453 -0
- data/docs/guides/columns/create.md +452 -0
- data/docs/guides/columns/metadata.md +492 -0
- data/docs/guides/columns/query.md +455 -0
- data/docs/guides/columns/update-multiple.md +459 -0
- data/docs/guides/columns/update-values.md +509 -0
- data/docs/guides/files/add-to-column.md +40 -0
- data/docs/guides/files/add-to-update.md +37 -0
- data/docs/guides/files/clear-column.md +33 -0
- data/docs/guides/first-request.md +285 -0
- data/docs/guides/folders/manage.md +750 -0
- data/docs/guides/groups/items.md +626 -0
- data/docs/guides/groups/manage.md +501 -0
- data/docs/guides/installation.md +169 -0
- data/docs/guides/items/create.md +493 -0
- data/docs/guides/items/delete.md +514 -0
- data/docs/guides/items/query.md +605 -0
- data/docs/guides/items/subitems.md +483 -0
- data/docs/guides/items/update.md +699 -0
- data/docs/guides/updates/manage.md +619 -0
- data/docs/guides/use-cases/dashboard.md +1421 -0
- data/docs/guides/use-cases/import.md +1962 -0
- data/docs/guides/use-cases/task-management.md +1381 -0
- data/docs/guides/workspaces/manage.md +502 -0
- data/docs/index.md +69 -0
- data/docs/package-lock.json +2468 -0
- data/docs/package.json +13 -0
- data/docs/reference/client.md +540 -0
- data/docs/reference/configuration.md +586 -0
- data/docs/reference/errors.md +693 -0
- data/docs/reference/resources/account.md +208 -0
- data/docs/reference/resources/activity-log.md +369 -0
- data/docs/reference/resources/board-view.md +359 -0
- data/docs/reference/resources/board.md +393 -0
- data/docs/reference/resources/column.md +543 -0
- data/docs/reference/resources/file.md +236 -0
- data/docs/reference/resources/folder.md +386 -0
- data/docs/reference/resources/group.md +507 -0
- data/docs/reference/resources/item.md +348 -0
- data/docs/reference/resources/subitem.md +267 -0
- data/docs/reference/resources/update.md +259 -0
- data/docs/reference/resources/workspace.md +213 -0
- data/docs/reference/response.md +560 -0
- data/docs/tutorial/first-integration.md +713 -0
- data/lib/monday/client.rb +24 -0
- data/lib/monday/configuration.rb +5 -0
- data/lib/monday/request.rb +15 -0
- data/lib/monday/resources/base.rb +4 -0
- data/lib/monday/resources/file.rb +56 -0
- data/lib/monday/util.rb +1 -0
- data/lib/monday/version.rb +1 -1
- metadata +87 -4
|
@@ -0,0 +1,750 @@
|
|
|
1
|
+
# Manage Folders
|
|
2
|
+
|
|
3
|
+
Organize boards into folders within workspaces for better structure and navigation.
|
|
4
|
+
|
|
5
|
+
## Query Folders
|
|
6
|
+
|
|
7
|
+
List all folders in your account:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
require "monday_ruby"
|
|
11
|
+
|
|
12
|
+
Monday.configure do |config|
|
|
13
|
+
config.token = ENV["MONDAY_TOKEN"]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
client = Monday::Client.new
|
|
17
|
+
|
|
18
|
+
response = client.folder.query
|
|
19
|
+
|
|
20
|
+
if response.success?
|
|
21
|
+
folders = response.body.dig("data", "folders")
|
|
22
|
+
|
|
23
|
+
puts "Folders in your account:"
|
|
24
|
+
folders.each do |folder|
|
|
25
|
+
puts " • #{folder['name']} (ID: #{folder['id']})"
|
|
26
|
+
end
|
|
27
|
+
else
|
|
28
|
+
puts "Failed to retrieve folders"
|
|
29
|
+
end
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Output:**
|
|
33
|
+
```
|
|
34
|
+
Folders in your account:
|
|
35
|
+
• LE Development Team (ID: 10918734)
|
|
36
|
+
• CRM (ID: 10977318)
|
|
37
|
+
• Projects (ID: 12772091)
|
|
38
|
+
• Documentation (ID: 13201660)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Query Specific Folders
|
|
42
|
+
|
|
43
|
+
Retrieve folders by ID:
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
response = client.folder.query(
|
|
47
|
+
args: { ids: [10918734, 10977318] },
|
|
48
|
+
select: ["id", "name", "color"]
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if response.success?
|
|
52
|
+
folders = response.body.dig("data", "folders")
|
|
53
|
+
|
|
54
|
+
folders.each do |folder|
|
|
55
|
+
puts "#{folder['name']}: #{folder['color']}"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Get Folder Details
|
|
61
|
+
|
|
62
|
+
Query with nested fields to see folder contents:
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
response = client.folder.query(
|
|
66
|
+
select: [
|
|
67
|
+
"id",
|
|
68
|
+
"name",
|
|
69
|
+
"color",
|
|
70
|
+
"created_at",
|
|
71
|
+
{
|
|
72
|
+
workspace: ["id", "name"],
|
|
73
|
+
children: ["id", "name", "type"]
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
if response.success?
|
|
79
|
+
folders = response.body.dig("data", "folders")
|
|
80
|
+
|
|
81
|
+
folders.first(3).each do |folder|
|
|
82
|
+
workspace_name = folder.dig("workspace", "name")
|
|
83
|
+
board_count = folder["children"]&.count || 0
|
|
84
|
+
|
|
85
|
+
puts "\n#{folder['name']}"
|
|
86
|
+
puts " Workspace: #{workspace_name}"
|
|
87
|
+
puts " Boards: #{board_count}"
|
|
88
|
+
puts " Created: #{folder['created_at']}"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Output:**
|
|
94
|
+
```
|
|
95
|
+
LE Development Team
|
|
96
|
+
Workspace: Main Workspace
|
|
97
|
+
Boards: 5
|
|
98
|
+
Created: 2024-01-15T10:30:00Z
|
|
99
|
+
|
|
100
|
+
CRM
|
|
101
|
+
Workspace: Sales Workspace
|
|
102
|
+
Boards: 3
|
|
103
|
+
Created: 2024-02-20T14:22:00Z
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Create a Folder
|
|
107
|
+
|
|
108
|
+
Create a new folder within a workspace:
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
require "monday_ruby"
|
|
112
|
+
|
|
113
|
+
Monday.configure do |config|
|
|
114
|
+
config.token = ENV["MONDAY_TOKEN"]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
client = Monday::Client.new
|
|
118
|
+
|
|
119
|
+
# First, get your workspace ID
|
|
120
|
+
workspace_response = client.workspace.query(
|
|
121
|
+
select: ["id", "name"]
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
workspace = workspace_response.body.dig("data", "workspaces", 0)
|
|
125
|
+
workspace_id = workspace["id"]
|
|
126
|
+
|
|
127
|
+
# Create folder in that workspace
|
|
128
|
+
response = client.folder.create(
|
|
129
|
+
args: {
|
|
130
|
+
workspace_id: workspace_id,
|
|
131
|
+
name: "Database boards"
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
if response.success?
|
|
136
|
+
folder = response.body.dig("data", "create_folder")
|
|
137
|
+
puts "✓ Created folder: #{folder['name']}"
|
|
138
|
+
puts " ID: #{folder['id']}"
|
|
139
|
+
else
|
|
140
|
+
puts "✗ Failed to create folder"
|
|
141
|
+
end
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Output:**
|
|
145
|
+
```
|
|
146
|
+
✓ Created folder: Database boards
|
|
147
|
+
ID: 15476755
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Create with Color
|
|
151
|
+
|
|
152
|
+
Add a color to help visually identify folders:
|
|
153
|
+
|
|
154
|
+
```ruby
|
|
155
|
+
response = client.folder.create(
|
|
156
|
+
args: {
|
|
157
|
+
workspace_id: 8529962,
|
|
158
|
+
name: "Q1 2024 Projects",
|
|
159
|
+
color: "#FF5AC4" # Pink
|
|
160
|
+
},
|
|
161
|
+
select: ["id", "name", "color"]
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
if response.success?
|
|
165
|
+
folder = response.body.dig("data", "create_folder")
|
|
166
|
+
puts "Created #{folder['name']} with color #{folder['color']}"
|
|
167
|
+
end
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Common colors:**
|
|
171
|
+
```ruby
|
|
172
|
+
colors = {
|
|
173
|
+
red: "#E2445C",
|
|
174
|
+
orange: "#FDAB3D",
|
|
175
|
+
yellow: "#FFCB00",
|
|
176
|
+
green: "#00C875",
|
|
177
|
+
blue: "#0086C0",
|
|
178
|
+
purple: "#A25DDC",
|
|
179
|
+
pink: "#FF5AC4",
|
|
180
|
+
gray: "#C4C4C4"
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
response = client.folder.create(
|
|
184
|
+
args: {
|
|
185
|
+
workspace_id: 8529962,
|
|
186
|
+
name: "Engineering",
|
|
187
|
+
color: colors[:blue]
|
|
188
|
+
}
|
|
189
|
+
)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Create Multiple Folders
|
|
193
|
+
|
|
194
|
+
Organize workspace with multiple folders:
|
|
195
|
+
|
|
196
|
+
```ruby
|
|
197
|
+
workspace_id = 8529962
|
|
198
|
+
folders = ["Design", "Engineering", "Marketing", "Sales"]
|
|
199
|
+
|
|
200
|
+
folders.each do |folder_name|
|
|
201
|
+
response = client.folder.create(
|
|
202
|
+
args: {
|
|
203
|
+
workspace_id: workspace_id,
|
|
204
|
+
name: folder_name
|
|
205
|
+
}
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
if response.success?
|
|
209
|
+
folder = response.body.dig("data", "create_folder")
|
|
210
|
+
puts "✓ Created: #{folder['name']}"
|
|
211
|
+
else
|
|
212
|
+
puts "✗ Failed to create: #{folder_name}"
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Rate limiting: pause between requests
|
|
216
|
+
sleep(0.3)
|
|
217
|
+
end
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Output:**
|
|
221
|
+
```
|
|
222
|
+
✓ Created: Design
|
|
223
|
+
✓ Created: Engineering
|
|
224
|
+
✓ Created: Marketing
|
|
225
|
+
✓ Created: Sales
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Create Subfolder
|
|
229
|
+
|
|
230
|
+
Create a folder within another folder:
|
|
231
|
+
|
|
232
|
+
```ruby
|
|
233
|
+
# Create parent folder first
|
|
234
|
+
parent_response = client.folder.create(
|
|
235
|
+
args: {
|
|
236
|
+
workspace_id: 8529962,
|
|
237
|
+
name: "Projects"
|
|
238
|
+
}
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
parent_id = parent_response.body.dig("data", "create_folder", "id")
|
|
242
|
+
|
|
243
|
+
# Create subfolder
|
|
244
|
+
response = client.folder.create(
|
|
245
|
+
args: {
|
|
246
|
+
workspace_id: 8529962,
|
|
247
|
+
name: "Active Projects",
|
|
248
|
+
parent_folder_id: parent_id
|
|
249
|
+
}
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
if response.success?
|
|
253
|
+
subfolder = response.body.dig("data", "create_folder")
|
|
254
|
+
puts "Created subfolder: #{subfolder['name']}"
|
|
255
|
+
end
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Update Folder Name
|
|
259
|
+
|
|
260
|
+
Rename an existing folder:
|
|
261
|
+
|
|
262
|
+
```ruby
|
|
263
|
+
require "monday_ruby"
|
|
264
|
+
|
|
265
|
+
Monday.configure do |config|
|
|
266
|
+
config.token = ENV["MONDAY_TOKEN"]
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
client = Monday::Client.new
|
|
270
|
+
|
|
271
|
+
response = client.folder.update(
|
|
272
|
+
args: {
|
|
273
|
+
folder_id: 15476750,
|
|
274
|
+
name: "Cool boards"
|
|
275
|
+
}
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
if response.success?
|
|
279
|
+
folder = response.body.dig("data", "update_folder")
|
|
280
|
+
puts "✓ Updated folder ID: #{folder['id']}"
|
|
281
|
+
else
|
|
282
|
+
puts "✗ Failed to update folder"
|
|
283
|
+
end
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Update Folder Color
|
|
287
|
+
|
|
288
|
+
Change the folder's visual appearance:
|
|
289
|
+
|
|
290
|
+
```ruby
|
|
291
|
+
response = client.folder.update(
|
|
292
|
+
args: {
|
|
293
|
+
folder_id: 15476750,
|
|
294
|
+
color: "#00C875" # Green
|
|
295
|
+
},
|
|
296
|
+
select: ["id", "name", "color"]
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
if response.success?
|
|
300
|
+
folder = response.body.dig("data", "update_folder")
|
|
301
|
+
puts "Updated #{folder['name']} to #{folder['color']}"
|
|
302
|
+
end
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Update Multiple Attributes
|
|
306
|
+
|
|
307
|
+
Change both name and color:
|
|
308
|
+
|
|
309
|
+
```ruby
|
|
310
|
+
response = client.folder.update(
|
|
311
|
+
args: {
|
|
312
|
+
folder_id: 15476750,
|
|
313
|
+
name: "Completed Projects",
|
|
314
|
+
color: "#C4C4C4" # Gray
|
|
315
|
+
},
|
|
316
|
+
select: ["id", "name", "color"]
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
if response.success?
|
|
320
|
+
folder = response.body.dig("data", "update_folder")
|
|
321
|
+
puts "✓ Updated folder:"
|
|
322
|
+
puts " Name: #{folder['name']}"
|
|
323
|
+
puts " Color: #{folder['color']}"
|
|
324
|
+
end
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Move Folder to Different Parent
|
|
328
|
+
|
|
329
|
+
Reorganize folder hierarchy:
|
|
330
|
+
|
|
331
|
+
```ruby
|
|
332
|
+
# Move folder to different parent
|
|
333
|
+
response = client.folder.update(
|
|
334
|
+
args: {
|
|
335
|
+
folder_id: 15476750,
|
|
336
|
+
parent_folder_id: 12345678 # New parent folder ID
|
|
337
|
+
}
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
if response.success?
|
|
341
|
+
puts "Folder moved to new parent"
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
# Move folder to workspace root (remove from parent)
|
|
345
|
+
response = client.folder.update(
|
|
346
|
+
args: {
|
|
347
|
+
folder_id: 15476750,
|
|
348
|
+
parent_folder_id: nil
|
|
349
|
+
}
|
|
350
|
+
)
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Delete Folders
|
|
354
|
+
|
|
355
|
+
Remove folders that are no longer needed:
|
|
356
|
+
|
|
357
|
+
```ruby
|
|
358
|
+
require "monday_ruby"
|
|
359
|
+
|
|
360
|
+
Monday.configure do |config|
|
|
361
|
+
config.token = ENV["MONDAY_TOKEN"]
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
client = Monday::Client.new
|
|
365
|
+
|
|
366
|
+
response = client.folder.delete(
|
|
367
|
+
args: { folder_id: 15476753 }
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
if response.success?
|
|
371
|
+
folder = response.body.dig("data", "delete_folder")
|
|
372
|
+
puts "✓ Deleted folder ID: #{folder['id']}"
|
|
373
|
+
else
|
|
374
|
+
puts "✗ Failed to delete folder"
|
|
375
|
+
end
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
::: warning <span style="display: inline-flex; align-items: center; gap: 6px;"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>Boards Are Preserved</span>
|
|
379
|
+
Deleting a folder does NOT delete the boards inside it. Boards are moved to the workspace root.
|
|
380
|
+
:::
|
|
381
|
+
|
|
382
|
+
### Delete Multiple Folders
|
|
383
|
+
|
|
384
|
+
Clean up several folders at once:
|
|
385
|
+
|
|
386
|
+
```ruby
|
|
387
|
+
folder_ids = [15476753, 15476754, 15476755]
|
|
388
|
+
|
|
389
|
+
folder_ids.each do |folder_id|
|
|
390
|
+
response = client.folder.delete(
|
|
391
|
+
args: { folder_id: folder_id }
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
if response.success?
|
|
395
|
+
puts "✓ Deleted folder #{folder_id}"
|
|
396
|
+
else
|
|
397
|
+
puts "✗ Failed to delete folder #{folder_id}"
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
sleep(0.3)
|
|
401
|
+
end
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Safely Delete Empty Folders
|
|
405
|
+
|
|
406
|
+
Check if folder is empty before deleting:
|
|
407
|
+
|
|
408
|
+
```ruby
|
|
409
|
+
# Query folder with children
|
|
410
|
+
response = client.folder.query(
|
|
411
|
+
select: [
|
|
412
|
+
"id",
|
|
413
|
+
"name",
|
|
414
|
+
{
|
|
415
|
+
children: ["id"]
|
|
416
|
+
}
|
|
417
|
+
]
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
if response.success?
|
|
421
|
+
folders = response.body.dig("data", "folders")
|
|
422
|
+
|
|
423
|
+
folders.each do |folder|
|
|
424
|
+
children_count = folder["children"]&.count || 0
|
|
425
|
+
|
|
426
|
+
if children_count == 0
|
|
427
|
+
delete_response = client.folder.delete(
|
|
428
|
+
args: { folder_id: folder["id"] }
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
if delete_response.success?
|
|
432
|
+
puts "✓ Deleted empty folder: #{folder['name']}"
|
|
433
|
+
end
|
|
434
|
+
else
|
|
435
|
+
puts "⊘ Skipped #{folder['name']} (#{children_count} boards)"
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Error Handling
|
|
442
|
+
|
|
443
|
+
Handle common folder operation errors:
|
|
444
|
+
|
|
445
|
+
```ruby
|
|
446
|
+
def create_folder_safe(client, workspace_id, name)
|
|
447
|
+
response = client.folder.create(
|
|
448
|
+
args: {
|
|
449
|
+
workspace_id: workspace_id,
|
|
450
|
+
name: name
|
|
451
|
+
}
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
if response.success?
|
|
455
|
+
folder = response.body.dig("data", "create_folder")
|
|
456
|
+
puts "✓ Created: #{folder['name']} (ID: #{folder['id']})"
|
|
457
|
+
folder['id']
|
|
458
|
+
else
|
|
459
|
+
puts "✗ Failed to create folder: #{name}"
|
|
460
|
+
puts " Status: #{response.status}"
|
|
461
|
+
|
|
462
|
+
if response.body["errors"]
|
|
463
|
+
response.body["errors"].each do |error|
|
|
464
|
+
puts " Error: #{error['message']}"
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
nil
|
|
469
|
+
end
|
|
470
|
+
rescue Monday::AuthorizationError
|
|
471
|
+
puts "✗ Invalid API token"
|
|
472
|
+
nil
|
|
473
|
+
rescue Monday::Error => e
|
|
474
|
+
puts "✗ API error: #{e.message}"
|
|
475
|
+
nil
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
# Usage
|
|
479
|
+
folder_id = create_folder_safe(client, 8529962, "New Folder")
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Handle Delete Errors
|
|
483
|
+
|
|
484
|
+
Gracefully handle non-existent folders:
|
|
485
|
+
|
|
486
|
+
```ruby
|
|
487
|
+
def delete_folder_safe(client, folder_id)
|
|
488
|
+
response = client.folder.delete(
|
|
489
|
+
args: { folder_id: folder_id }
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
if response.success?
|
|
493
|
+
puts "✓ Deleted folder #{folder_id}"
|
|
494
|
+
true
|
|
495
|
+
else
|
|
496
|
+
puts "✗ Failed to delete folder #{folder_id}"
|
|
497
|
+
false
|
|
498
|
+
end
|
|
499
|
+
rescue Monday::ResourceNotFoundError
|
|
500
|
+
puts "✗ Folder #{folder_id} not found"
|
|
501
|
+
false
|
|
502
|
+
rescue Monday::AuthorizationError
|
|
503
|
+
puts "✗ Invalid API token"
|
|
504
|
+
false
|
|
505
|
+
rescue Monday::Error => e
|
|
506
|
+
puts "✗ Error: #{e.message}"
|
|
507
|
+
false
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
# Usage
|
|
511
|
+
delete_folder_safe(client, 999999) # Non-existent folder
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Validate Before Update
|
|
515
|
+
|
|
516
|
+
Check folder exists before updating:
|
|
517
|
+
|
|
518
|
+
```ruby
|
|
519
|
+
def update_folder_safe(client, folder_id, updates)
|
|
520
|
+
# First verify folder exists
|
|
521
|
+
query_response = client.folder.query(
|
|
522
|
+
args: { ids: [folder_id] },
|
|
523
|
+
select: ["id", "name"]
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
folders = query_response.body.dig("data", "folders") || []
|
|
527
|
+
|
|
528
|
+
if folders.empty?
|
|
529
|
+
puts "✗ Folder #{folder_id} not found"
|
|
530
|
+
return false
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
# Folder exists, proceed with update
|
|
534
|
+
response = client.folder.update(
|
|
535
|
+
args: updates.merge(folder_id: folder_id)
|
|
536
|
+
)
|
|
537
|
+
|
|
538
|
+
if response.success?
|
|
539
|
+
puts "✓ Updated folder #{folder_id}"
|
|
540
|
+
true
|
|
541
|
+
else
|
|
542
|
+
puts "✗ Failed to update folder"
|
|
543
|
+
false
|
|
544
|
+
end
|
|
545
|
+
rescue Monday::Error => e
|
|
546
|
+
puts "✗ Error: #{e.message}"
|
|
547
|
+
false
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
# Usage
|
|
551
|
+
update_folder_safe(client, 15476750, { name: "New Name" })
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
## Complete Example
|
|
555
|
+
|
|
556
|
+
Full workflow for managing folders:
|
|
557
|
+
|
|
558
|
+
```ruby
|
|
559
|
+
require "monday_ruby"
|
|
560
|
+
require "dotenv/load"
|
|
561
|
+
|
|
562
|
+
Monday.configure do |config|
|
|
563
|
+
config.token = ENV["MONDAY_TOKEN"]
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
client = Monday::Client.new
|
|
567
|
+
|
|
568
|
+
# 1. Get workspace
|
|
569
|
+
workspace_response = client.workspace.query(
|
|
570
|
+
select: ["id", "name"]
|
|
571
|
+
)
|
|
572
|
+
|
|
573
|
+
workspace = workspace_response.body.dig("data", "workspaces", 0)
|
|
574
|
+
workspace_id = workspace["id"]
|
|
575
|
+
|
|
576
|
+
puts "Working in workspace: #{workspace['name']}"
|
|
577
|
+
puts "#{'=' * 50}"
|
|
578
|
+
|
|
579
|
+
# 2. Create new folder
|
|
580
|
+
create_response = client.folder.create(
|
|
581
|
+
args: {
|
|
582
|
+
workspace_id: workspace_id,
|
|
583
|
+
name: "Q1 2024 Projects",
|
|
584
|
+
color: "#00C875"
|
|
585
|
+
},
|
|
586
|
+
select: ["id", "name", "color"]
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
if create_response.success?
|
|
590
|
+
folder = create_response.body.dig("data", "create_folder")
|
|
591
|
+
|
|
592
|
+
puts "\n✓ Created Folder"
|
|
593
|
+
puts " ID: #{folder['id']}"
|
|
594
|
+
puts " Name: #{folder['name']}"
|
|
595
|
+
puts " Color: #{folder['color']}"
|
|
596
|
+
|
|
597
|
+
folder_id = folder["id"]
|
|
598
|
+
|
|
599
|
+
# 3. Update folder name after creation
|
|
600
|
+
sleep(1) # Brief pause
|
|
601
|
+
|
|
602
|
+
update_response = client.folder.update(
|
|
603
|
+
args: {
|
|
604
|
+
folder_id: folder_id,
|
|
605
|
+
name: "Q1 2024 Active Projects"
|
|
606
|
+
},
|
|
607
|
+
select: ["id", "name"]
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
if update_response.success?
|
|
611
|
+
puts "\n✓ Updated Folder Name"
|
|
612
|
+
puts " ID: #{folder_id}"
|
|
613
|
+
puts " New Name: Q1 2024 Active Projects"
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
# 4. Query the folder to verify
|
|
617
|
+
sleep(1)
|
|
618
|
+
|
|
619
|
+
query_response = client.folder.query(
|
|
620
|
+
args: { ids: [folder_id] },
|
|
621
|
+
select: [
|
|
622
|
+
"id",
|
|
623
|
+
"name",
|
|
624
|
+
"color",
|
|
625
|
+
{
|
|
626
|
+
workspace: ["id", "name"]
|
|
627
|
+
}
|
|
628
|
+
]
|
|
629
|
+
)
|
|
630
|
+
|
|
631
|
+
if query_response.success?
|
|
632
|
+
queried_folder = query_response.body.dig("data", "folders", 0)
|
|
633
|
+
|
|
634
|
+
puts "\n✓ Verified Folder"
|
|
635
|
+
puts " Name: #{queried_folder['name']}"
|
|
636
|
+
puts " Color: #{queried_folder['color']}"
|
|
637
|
+
puts " Workspace: #{queried_folder.dig('workspace', 'name')}"
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
# 5. Clean up - delete the folder
|
|
641
|
+
sleep(1)
|
|
642
|
+
|
|
643
|
+
delete_response = client.folder.delete(
|
|
644
|
+
args: { folder_id: folder_id }
|
|
645
|
+
)
|
|
646
|
+
|
|
647
|
+
if delete_response.success?
|
|
648
|
+
puts "\n✓ Deleted Folder"
|
|
649
|
+
puts " ID: #{folder_id}"
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
puts "\n#{'=' * 50}"
|
|
653
|
+
puts "Folder lifecycle complete!"
|
|
654
|
+
else
|
|
655
|
+
puts "\n✗ Failed to create folder"
|
|
656
|
+
end
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
**Output:**
|
|
660
|
+
```
|
|
661
|
+
Working in workspace: Main Workspace
|
|
662
|
+
==================================================
|
|
663
|
+
|
|
664
|
+
✓ Created Folder
|
|
665
|
+
ID: 15476755
|
|
666
|
+
Name: Q1 2024 Projects
|
|
667
|
+
Color: #00C875
|
|
668
|
+
|
|
669
|
+
✓ Updated Folder Name
|
|
670
|
+
ID: 15476755
|
|
671
|
+
New Name: Q1 2024 Active Projects
|
|
672
|
+
|
|
673
|
+
✓ Verified Folder
|
|
674
|
+
Name: Q1 2024 Active Projects
|
|
675
|
+
Color: #00C875
|
|
676
|
+
Workspace: Main Workspace
|
|
677
|
+
|
|
678
|
+
✓ Deleted Folder
|
|
679
|
+
ID: 15476755
|
|
680
|
+
|
|
681
|
+
==================================================
|
|
682
|
+
Folder lifecycle complete!
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
## Organize Workspace Structure
|
|
686
|
+
|
|
687
|
+
Create a complete folder hierarchy:
|
|
688
|
+
|
|
689
|
+
```ruby
|
|
690
|
+
workspace_id = 8529962
|
|
691
|
+
|
|
692
|
+
# Create department folders with color coding
|
|
693
|
+
departments = {
|
|
694
|
+
"Engineering" => "#0086C0", # Blue
|
|
695
|
+
"Product" => "#A25DDC", # Purple
|
|
696
|
+
"Marketing" => "#FF5AC4", # Pink
|
|
697
|
+
"Sales" => "#00C875", # Green
|
|
698
|
+
"Operations" => "#FDAB3D" # Orange
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
created_folders = []
|
|
702
|
+
|
|
703
|
+
departments.each do |name, color|
|
|
704
|
+
response = client.folder.create(
|
|
705
|
+
args: {
|
|
706
|
+
workspace_id: workspace_id,
|
|
707
|
+
name: name,
|
|
708
|
+
color: color
|
|
709
|
+
},
|
|
710
|
+
select: ["id", "name", "color"]
|
|
711
|
+
)
|
|
712
|
+
|
|
713
|
+
if response.success?
|
|
714
|
+
folder = response.body.dig("data", "create_folder")
|
|
715
|
+
created_folders << folder
|
|
716
|
+
puts "✓ Created #{folder['name']} (#{folder['color']})"
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
sleep(0.3)
|
|
720
|
+
end
|
|
721
|
+
|
|
722
|
+
puts "\nCreated #{created_folders.count} department folders"
|
|
723
|
+
|
|
724
|
+
# Create project folders within Engineering
|
|
725
|
+
engineering_folder = created_folders.find { |f| f["name"] == "Engineering" }
|
|
726
|
+
|
|
727
|
+
if engineering_folder
|
|
728
|
+
projects = ["Backend API", "Frontend App", "Mobile App"]
|
|
729
|
+
|
|
730
|
+
projects.each do |project|
|
|
731
|
+
response = client.folder.create(
|
|
732
|
+
args: {
|
|
733
|
+
workspace_id: workspace_id,
|
|
734
|
+
name: project,
|
|
735
|
+
parent_folder_id: engineering_folder["id"]
|
|
736
|
+
}
|
|
737
|
+
)
|
|
738
|
+
|
|
739
|
+
puts " ✓ Created #{project}" if response.success?
|
|
740
|
+
sleep(0.3)
|
|
741
|
+
end
|
|
742
|
+
end
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
## Next Steps
|
|
746
|
+
|
|
747
|
+
- [Create boards](/guides/boards/create)
|
|
748
|
+
- [Query boards](/guides/boards/query)
|
|
749
|
+
- [Board API reference](/reference/resources/board)
|
|
750
|
+
- [Folder API reference](/reference/resources/folder)
|