async-vikunja 1.0.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.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +362 -0
  3. data/lib/async/vikunja/admin.rb +97 -0
  4. data/lib/async/vikunja/assignees.rb +20 -0
  5. data/lib/async/vikunja/attachments.rb +51 -0
  6. data/lib/async/vikunja/auth.rb +52 -0
  7. data/lib/async/vikunja/bots.rb +43 -0
  8. data/lib/async/vikunja/buckets.rb +51 -0
  9. data/lib/async/vikunja/client.rb +76 -0
  10. data/lib/async/vikunja/comments.rb +31 -0
  11. data/lib/async/vikunja/error.rb +52 -0
  12. data/lib/async/vikunja/escape.rb +9 -0
  13. data/lib/async/vikunja/filters.rb +39 -0
  14. data/lib/async/vikunja/labels.rb +71 -0
  15. data/lib/async/vikunja/migration.rb +89 -0
  16. data/lib/async/vikunja/notifications.rb +45 -0
  17. data/lib/async/vikunja/page.rb +112 -0
  18. data/lib/async/vikunja/projects.rb +133 -0
  19. data/lib/async/vikunja/reactions.rb +19 -0
  20. data/lib/async/vikunja/redacted.rb +37 -0
  21. data/lib/async/vikunja/representation.rb +73 -0
  22. data/lib/async/vikunja/service.rb +137 -0
  23. data/lib/async/vikunja/sessions.rb +29 -0
  24. data/lib/async/vikunja/settings.rb +67 -0
  25. data/lib/async/vikunja/sharing.rb +131 -0
  26. data/lib/async/vikunja/submit.rb +97 -0
  27. data/lib/async/vikunja/subscriptions.rb +21 -0
  28. data/lib/async/vikunja/tasks.rb +207 -0
  29. data/lib/async/vikunja/teams.rb +85 -0
  30. data/lib/async/vikunja/time_entries.rb +55 -0
  31. data/lib/async/vikunja/tokens.rb +59 -0
  32. data/lib/async/vikunja/users.rb +107 -0
  33. data/lib/async/vikunja/version.rb +10 -0
  34. data/lib/async/vikunja/views.rb +75 -0
  35. data/lib/async/vikunja/webhooks.rb +55 -0
  36. data/lib/async/vikunja/wrapper.rb +75 -0
  37. data/lib/async/vikunja.rb +2 -0
  38. data/license.md +21 -0
  39. metadata +105 -0
@@ -0,0 +1,207 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ module TaskFields
6
+ def id = self.value[:id]
7
+
8
+ def title = self.value[:title]
9
+
10
+ def description = self.value[:description]
11
+
12
+ def identifier = self.value[:identifier]
13
+
14
+ def index = self.value[:index]
15
+
16
+ def done = self.value[:done]
17
+
18
+ def done_at = self.value[:done_at]
19
+
20
+ def due_date = self.value[:due_date]
21
+
22
+ def start_date = self.value[:start_date]
23
+
24
+ def end_date = self.value[:end_date]
25
+
26
+ def hex_color = self.value[:hex_color]
27
+
28
+ def percent_done = self.value[:percent_done]
29
+
30
+ def position = self.value[:position]
31
+
32
+ def priority = self.value[:priority]
33
+
34
+ def project_id = self.value[:project_id]
35
+
36
+ def bucket_id = self.value[:bucket_id]
37
+
38
+ def cover_image_attachment_id = self.value[:cover_image_attachment_id]
39
+
40
+ def comment_count = self.value[:comment_count]
41
+
42
+ def time_entries_count = self.value[:time_entries_count]
43
+
44
+ def repeat_after = self.value[:repeat_after]
45
+
46
+ def repeat_mode = self.value[:repeat_mode]
47
+
48
+ def is_favorite = self.value[:is_favorite]
49
+
50
+ def is_unread = self.value[:is_unread]
51
+
52
+ def deleted_at = self.value[:deleted_at]
53
+
54
+ def created = self.value[:created]
55
+
56
+ def updated = self.value[:updated]
57
+
58
+ def reactions = self.value[:reactions]
59
+
60
+ def related_tasks = self.value[:related_tasks]
61
+
62
+ def created_by = self.nested(User, self.value[:created_by])
63
+
64
+ def subscription = self.nested(Subscription, self.value[:subscription])
65
+
66
+ def assignees = self.nested_list(User, self.value[:assignees])
67
+
68
+ def attachments = self.nested_list(TaskAttachment, self.value[:attachments])
69
+
70
+ def buckets = self.nested_list(Bucket, self.value[:buckets])
71
+
72
+ def comments = self.nested_list(TaskComment, self.value[:comments])
73
+
74
+ def labels = self.nested_list(Label, self.value[:labels])
75
+
76
+ def reminders = self.nested_list(TaskReminder, self.value[:reminders])
77
+
78
+ def done? = self.done == true
79
+
80
+ def favorite? = self.is_favorite == true
81
+ end
82
+
83
+ class Task < Representation
84
+ include TaskFields
85
+
86
+ def task_comments(**parameters) = Collection.for(@resource, "comments", TaskCommentPage, **parameters)
87
+
88
+ def task_attachments(**parameters) = Collection.for(@resource, "attachments", TaskAttachmentPage, **parameters)
89
+
90
+ def task_labels(**parameters) = Collection.for(@resource, "labels", TaskLabelPage, **parameters)
91
+
92
+ def task_assignees(**parameters) = Collection.for(@resource, "assignees", TaskAssigneePage, **parameters)
93
+
94
+ def task_time_entries(**parameters) = Collection.for(@resource, "time-entries", TaskTimeEntryPage, **parameters)
95
+
96
+ def comment(id) = TaskComment.new(@resource.with(path: "comments/" + Vikunja.escape(id)))
97
+
98
+ def attachment(id) = TaskAttachment.new(@resource.with(path: "attachments/" + Vikunja.escape(id)))
99
+
100
+ def download_attachment(id) = Download.new(@resource.with(path: "attachments/" + Vikunja.escape(id)))
101
+
102
+ def create_comment(payload) = self.submit(TaskComment, @resource.with(path: "comments"), payload, identify: true)
103
+
104
+ def upload_attachments(parts) = self.upload(AttachmentUploadResult, @resource.with(path: "attachments"), parts)
105
+
106
+ def add_label(label) = self.submit(LabelTask, @resource.with(path: "labels"), {label_id: label})
107
+
108
+ def replace_labels(labels) = self.submit(LabelTaskBulk, @resource.with(path: "labels/bulk"), {labels: labels}, method: :put)
109
+
110
+ def remove_label(label) = self.discard(@resource.with(path: "labels/" + Vikunja.escape(label)))
111
+
112
+ def add_assignee(user) = self.submit(TaskAssginee, @resource.with(path: "assignees"), {user_id: user})
113
+
114
+ def replace_assignees(assignees) = self.submit(BulkAssignees, @resource.with(path: "assignees/bulk"), {assignees: assignees}, method: :put)
115
+
116
+ def remove_assignee(user) = self.discard(@resource.with(path: "assignees/" + Vikunja.escape(user)))
117
+
118
+ def add_relation(payload) = self.submit(TaskRelation, @resource.with(path: "relations"), payload)
119
+
120
+ def remove_relation(kind, other) = self.discard(@resource.with(path: "relations/" + Vikunja.escape(kind) + "/" + Vikunja.escape(other)))
121
+
122
+ def reposition(payload) = self.submit(TaskPosition, @resource.with(path: "position"), payload, method: :put)
123
+
124
+ def mark_read = self.submit(Message, @resource.with(path: "read"), nil, method: :put)
125
+
126
+ def duplicate = self.submit(TaskDuplicate, @resource.with(path: "duplicate"))
127
+
128
+ def update(payload) = self.submit(Task, @resource, payload, method: :put)
129
+
130
+ def patch(payload) = self.merge_patch(Task, @resource, payload)
131
+
132
+ def delete = self.discard(@resource)
133
+ end
134
+
135
+ class TaskReadOneBody < Representation
136
+ include TaskFields
137
+
138
+ def max_permission = self.value[:max_permission]
139
+ end
140
+
141
+ class TaskReminder < Representation
142
+ def reminder = self.value[:reminder]
143
+
144
+ def relative_period = self.value[:relative_period]
145
+
146
+ def relative_to = self.value[:relative_to]
147
+ end
148
+
149
+ class TaskRelation < Representation
150
+ def task_id = self.value[:task_id]
151
+
152
+ def other_task_id = self.value[:other_task_id]
153
+
154
+ def relation_kind = self.value[:relation_kind]
155
+
156
+ def created = self.value[:created]
157
+
158
+ def created_by = self.nested(User, self.value[:created_by])
159
+ end
160
+
161
+ class TaskPosition < Representation
162
+ def task_id = self.value[:task_id]
163
+
164
+ def project_view_id = self.value[:project_view_id]
165
+
166
+ def position = self.value[:position]
167
+ end
168
+
169
+ class TaskDuplicate < Representation
170
+ def duplicated_task = self.nested(Task, self.value[:duplicated_task])
171
+ end
172
+
173
+ class BulkTaskCreation < Representation
174
+ def tasks = self.nested_list(Task, self.value[:tasks])
175
+ end
176
+
177
+ class BulkTask < Representation
178
+ def task_ids = Array(self.value[:task_ids])
179
+
180
+ def fields = Array(self.value[:fields])
181
+
182
+ def values = self.nested(Task, self.value[:values])
183
+
184
+ def tasks = self.nested_list(Task, self.value[:tasks])
185
+ end
186
+
187
+ class TaskPage < Page
188
+ MEMBER = Task
189
+ end
190
+
191
+ class ProjectTaskPage < TaskPage
192
+ def member_path(record) = "../../../tasks/" + Vikunja.escape(record[:id])
193
+ end
194
+
195
+ class ProjectViewTaskPage < TaskPage
196
+ def member_path(record) = "../../../../../tasks/" + Vikunja.escape(record[:id])
197
+ end
198
+
199
+ module Tasks
200
+ def tasks(**parameters) = Collection.for(self, "tasks", TaskPage, **parameters)
201
+
202
+ def task(id) = Task.new(self.with(path: "tasks/" + Vikunja.escape(id)))
203
+
204
+ def update_tasks(payload) = self.submit(BulkTask, self.with(path: "tasks/bulk"), payload, method: :put)
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,85 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ class Team < Representation
6
+ def id = self.value[:id]
7
+
8
+ def name = self.value[:name]
9
+
10
+ def description = self.value[:description]
11
+
12
+ def is_public = self.value[:is_public]
13
+
14
+ def external_id = self.value[:external_id]
15
+
16
+ def created = self.value[:created]
17
+
18
+ def updated = self.value[:updated]
19
+
20
+ def created_by = self.nested(User, self.value[:created_by])
21
+
22
+ def members = self.nested_list(TeamUser, self.value[:members])
23
+
24
+ def max_permission = self.value[:max_permission]
25
+
26
+ def public? = self.is_public == true
27
+
28
+ def add_member(payload) = self.submit(TeamMember, @resource.with(path: "members"), payload)
29
+
30
+ def remove_member(user) = self.discard(@resource.with(path: "members/" + Vikunja.escape(user)))
31
+
32
+ def toggle_admin(user) = self.submit(TeamMember, @resource.with(path: "members/" + Vikunja.escape(user) + "/admin"), nil)
33
+
34
+ def update(payload) = self.submit(Team, @resource, payload, method: :put)
35
+
36
+ def patch(payload) = self.merge_patch(Team, @resource, payload)
37
+
38
+ def delete = self.discard(@resource)
39
+ end
40
+
41
+ class TeamMember < Representation
42
+ def id = self.value[:id]
43
+
44
+ def username = self.value[:username]
45
+
46
+ def admin = self.value[:admin]
47
+
48
+ def created = self.value[:created]
49
+
50
+ def admin? = self.admin == true
51
+ end
52
+
53
+ class TeamUser < Representation
54
+ def id = self.value[:id]
55
+
56
+ def username = self.value[:username]
57
+
58
+ def name = self.value[:name]
59
+
60
+ def email = self.value[:email]
61
+
62
+ def admin = self.value[:admin]
63
+
64
+ def bot_owner_id = self.value[:bot_owner_id]
65
+
66
+ def created = self.value[:created]
67
+
68
+ def updated = self.value[:updated]
69
+
70
+ def admin? = self.admin == true
71
+ end
72
+
73
+ class TeamPage < Page
74
+ MEMBER = Team
75
+ end
76
+
77
+ module Teams
78
+ def teams(**parameters) = Collection.for(self, "teams", TeamPage, **parameters)
79
+
80
+ def team(id) = Team.new(self.with(path: "teams/" + Vikunja.escape(id)))
81
+
82
+ def create_team(payload) = self.submit(Team, self.with(path: "teams"), payload, identify: true)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,55 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ class TimeEntry < Representation
6
+ def id = self.value[:id]
7
+
8
+ def comment = self.value[:comment]
9
+
10
+ def start_time = self.value[:start_time]
11
+
12
+ def end_time = self.value[:end_time]
13
+
14
+ def project_id = self.value[:project_id]
15
+
16
+ def task_id = self.value[:task_id]
17
+
18
+ def user_id = self.value[:user_id]
19
+
20
+ def created = self.value[:created]
21
+
22
+ def updated = self.value[:updated]
23
+
24
+ def max_permission = self.value[:max_permission]
25
+
26
+ def update(payload) = self.submit(TimeEntry, @resource, payload, method: :put)
27
+
28
+ def patch(payload) = self.merge_patch(TimeEntry, @resource, payload)
29
+
30
+ def delete = self.discard(@resource)
31
+ end
32
+
33
+ class TimeEntryPage < Page
34
+ MEMBER = TimeEntry
35
+ end
36
+
37
+ class ProjectTimeEntryPage < TimeEntryPage
38
+ def member_path(record) = "../../../time-entries/" + Vikunja.escape(record[:id])
39
+ end
40
+
41
+ class TaskTimeEntryPage < TimeEntryPage
42
+ def member_path(record) = "../../../time-entries/" + Vikunja.escape(record[:id])
43
+ end
44
+
45
+ module TimeEntries
46
+ def time_entries(**parameters) = Collection.for(self, "time-entries", TimeEntryPage, **parameters)
47
+
48
+ def time_entry(id) = TimeEntry.new(self.with(path: "time-entries/" + Vikunja.escape(id)))
49
+
50
+ def create_time_entry(payload) = self.submit(TimeEntry, self.with(path: "time-entries"), payload, identify: true)
51
+
52
+ def stop_timer = self.submit(TimeEntry, self.with(path: "time-entries/timer/stop"), nil)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,59 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ class APIToken < Representation
6
+ def id = self.value[:id]
7
+
8
+ def title = self.value[:title]
9
+
10
+ def owner_id = self.value[:owner_id]
11
+
12
+ def permissions = self.value[:permissions]
13
+
14
+ def expires_at = self.value[:expires_at]
15
+
16
+ def created = self.value[:created]
17
+
18
+ def token = self.value[:token]
19
+
20
+ def delete = self.discard(@resource)
21
+ end
22
+
23
+ class Token < Representation
24
+ def id = self.value[:id]
25
+
26
+ def created = self.value[:created]
27
+
28
+ def token = self.value[:token]
29
+
30
+ def delete = self.discard(@resource)
31
+ end
32
+
33
+ class APITokenPage < Page
34
+ MEMBER = APIToken
35
+ end
36
+
37
+ class CaldavTokenPage < Page
38
+ MEMBER = Token
39
+ end
40
+
41
+ module Tokens
42
+ def tokens(**parameters) = Collection.for(self, "tokens", APITokenPage, **parameters)
43
+
44
+ def create_token(payload) = self.submit(APIToken, self.with(path: "tokens"), payload, identify: true)
45
+
46
+ def delete_token(id) = self.discard(self.with(path: "tokens/" + Vikunja.escape(id)))
47
+
48
+ def test_token = Message.new(self.with(path: "token/test"))
49
+
50
+ def check_token = self.submit(Message, self.with(path: "token/test"), nil)
51
+
52
+ def caldav_tokens(**parameters) = Collection.for(self, "user/settings/token/caldav", CaldavTokenPage, **parameters)
53
+
54
+ def create_caldav_token = self.submit(Token, self.with(path: "user/settings/token/caldav"), nil, identify: true)
55
+
56
+ def delete_caldav_token(id) = self.discard(self.with(path: "user/settings/token/caldav/" + Vikunja.escape(id)))
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,107 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ class User < Representation
6
+ def id = self.value[:id]
7
+
8
+ def username = self.value[:username]
9
+
10
+ def name = self.value[:name]
11
+
12
+ def email = self.value[:email]
13
+
14
+ def bot_owner_id = self.value[:bot_owner_id]
15
+
16
+ def created = self.value[:created]
17
+
18
+ def updated = self.value[:updated]
19
+ end
20
+
21
+ class UserInfoBody < Representation
22
+ def id = self.value[:id]
23
+
24
+ def username = self.value[:username]
25
+
26
+ def name = self.value[:name]
27
+
28
+ def email = self.value[:email]
29
+
30
+ def bot_owner_id = self.value[:bot_owner_id]
31
+
32
+ def auth_provider = self.value[:auth_provider]
33
+
34
+ def is_admin = self.value[:is_admin]
35
+
36
+ def is_local_user = self.value[:is_local_user]
37
+
38
+ def deletion_scheduled_at = self.value[:deletion_scheduled_at]
39
+
40
+ def pending_email = self.value[:pending_email]
41
+
42
+ def settings = self.nested(UserGeneralSettings, self.value[:settings])
43
+
44
+ def created = self.value[:created]
45
+
46
+ def updated = self.value[:updated]
47
+
48
+ def admin? = self.is_admin == true
49
+
50
+ def local_user? = self.is_local_user == true
51
+ end
52
+
53
+ class UserActionMessageBody < Representation
54
+ def message = self.value[:message]
55
+ end
56
+
57
+ class UserExportStatus < Representation
58
+ def id = self.value[:id]
59
+
60
+ def created = self.value[:created]
61
+
62
+ def expires = self.value[:expires]
63
+
64
+ def size = self.value[:size]
65
+ end
66
+
67
+ class UserPage < Page
68
+ MEMBER = User
69
+ end
70
+
71
+ class UserSearchPage < Page
72
+ MEMBER = User
73
+
74
+ def member_resource(record) = @resource
75
+ end
76
+
77
+ module Users
78
+ def user = UserInfoBody.new(self.with(path: "user"))
79
+
80
+ def users(query) = UserSearchPage.new(self.with(path: "users", parameters: {q: query}))
81
+
82
+ def avatar(username, **parameters) = Download.new(self.with(path: "avatar/" + Vikunja.escape(username), parameters: parameters))
83
+
84
+ def timezones = Representation.new(self.with(path: "user/timezones"))
85
+
86
+ def change_password(old_password:, new_password:) = self.submit(UserActionMessageBody, self.with(path: "user/password"), {old_password: old_password, new_password: new_password})
87
+
88
+ def update_email(new_email:, password:) = self.submit(UserActionMessageBody, self.with(path: "user/settings/email"), {new_email: new_email, password: password}, method: :put)
89
+
90
+ def cancel_email_update = self.submit(UserActionMessageBody, self.with(path: "user/settings/email"), nil, method: :delete)
91
+
92
+ def resend_email_confirmation = self.submit(UserActionMessageBody, self.with(path: "user/settings/email/resend"), nil)
93
+
94
+ def export_status = UserExportStatus.new(self.with(path: "user/export"))
95
+
96
+ def request_export(password:) = self.submit(Message, self.with(path: "user/export/request"), {password: password})
97
+
98
+ def download_export(password:) = self.submit(Download, self.with(path: "user/export/download"), {password: password})
99
+
100
+ def request_deletion(password:) = self.discard(self.with(path: "user/deletion/request"), {password: password}, method: :post)
101
+
102
+ def confirm_deletion(token:) = self.discard(self.with(path: "user/deletion/confirm"), {token: token}, method: :post)
103
+
104
+ def cancel_deletion(password:) = self.discard(self.with(path: "user/deletion/cancel"), {password: password}, method: :post)
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2026, by Nathan Kidd.
5
+
6
+ module Async
7
+ module Vikunja
8
+ VERSION = "1.0.0"
9
+ end
10
+ end
@@ -0,0 +1,75 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ class ProjectView < Representation
6
+ def id = self.value[:id]
7
+
8
+ def title = self.value[:title]
9
+
10
+ def view_kind = self.value[:view_kind]
11
+
12
+ def position = self.value[:position]
13
+
14
+ def project_id = self.value[:project_id]
15
+
16
+ def bucket_configuration_mode = self.value[:bucket_configuration_mode]
17
+
18
+ def default_bucket_id = self.value[:default_bucket_id]
19
+
20
+ def done_bucket_id = self.value[:done_bucket_id]
21
+
22
+ def max_permission = self.value[:max_permission]
23
+
24
+ def created = self.value[:created]
25
+
26
+ def updated = self.value[:updated]
27
+
28
+ def filter = self.nested(TaskCollection, self.value[:filter])
29
+
30
+ def bucket_configuration = self.nested_list(ProjectViewBucketConfiguration, self.value[:bucket_configuration])
31
+
32
+ def buckets(**parameters) = Collection.for(@resource, "buckets", BucketPage, **parameters)
33
+
34
+ def tasks(**parameters) = Collection.for(@resource, "tasks", ProjectViewTaskPage, **parameters)
35
+
36
+ def buckets_with_tasks(**parameters) = BucketsWithTasks.new(@resource.with(path: "buckets/tasks", parameters: parameters))
37
+
38
+ def create_bucket(payload) = self.submit(Bucket, @resource.with(path: "buckets"), payload, identify: true)
39
+
40
+ def update_bucket(bucket, payload) = self.submit(Bucket, @resource.with(path: "buckets/" + Vikunja.escape(bucket)), payload, method: :put)
41
+
42
+ def remove_bucket(bucket) = self.discard(@resource.with(path: "buckets/" + Vikunja.escape(bucket)))
43
+
44
+ def move_task(bucket, payload) = self.submit(TaskBucket, @resource.with(path: "buckets/" + Vikunja.escape(bucket) + "/tasks"), payload, method: :put)
45
+
46
+ def update(payload) = self.submit(ProjectView, @resource, payload, method: :put)
47
+
48
+ def patch(payload) = self.merge_patch(ProjectView, @resource, payload)
49
+
50
+ def delete = self.discard(@resource)
51
+ end
52
+
53
+ class ProjectViewBucketConfiguration < Representation
54
+ def title = self.value[:title]
55
+
56
+ def filter = self.nested(TaskCollection, self.value[:filter])
57
+ end
58
+
59
+ class TaskCollection < Representation
60
+ def filter = self.value[:filter]
61
+
62
+ def filter_include_nulls = self.value[:filter_include_nulls]
63
+
64
+ def s = self.value[:s]
65
+
66
+ def sort_by = self.value[:sort_by]
67
+
68
+ def order_by = self.value[:order_by]
69
+ end
70
+
71
+ class ProjectViewPage < Page
72
+ MEMBER = ProjectView
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,55 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ class Webhook < Representation
6
+ def id = self.value[:id]
7
+
8
+ def target_url = self.value[:target_url]
9
+
10
+ def events = self.value[:events]
11
+
12
+ def project_id = self.value[:project_id]
13
+
14
+ def user_id = self.value[:user_id]
15
+
16
+ def secret = self.value[:secret]
17
+
18
+ def basic_auth_user = self.value[:basic_auth_user]
19
+
20
+ def basic_auth_password = self.value[:basic_auth_password]
21
+
22
+ def created = self.value[:created]
23
+
24
+ def updated = self.value[:updated]
25
+
26
+ def created_by = self.nested(User, self.value[:created_by])
27
+
28
+ def update(payload) = self.submit(Webhook, @resource, payload, method: :put)
29
+
30
+ def delete = self.discard(@resource)
31
+ end
32
+
33
+ class ProjectWebhookPage < Page
34
+ MEMBER = Webhook
35
+ end
36
+
37
+ class UserWebhookPage < Page
38
+ MEMBER = Webhook
39
+ end
40
+
41
+ module Webhooks
42
+ def webhook_events = Representation.new(self.with(path: "webhooks/events"))
43
+
44
+ def webhooks(**parameters) = Collection.for(self, "user/settings/webhooks", UserWebhookPage, **parameters)
45
+
46
+ def create_webhook(payload) = self.submit(Webhook, self.with(path: "user/settings/webhooks"), payload, identify: true)
47
+
48
+ def update_webhook(webhook, payload) = self.submit(Webhook, self.with(path: "user/settings/webhooks/" + Vikunja.escape(webhook)), payload, method: :put)
49
+
50
+ def remove_webhook(webhook) = self.discard(self.with(path: "user/settings/webhooks/" + Vikunja.escape(webhook)))
51
+
52
+ def user_webhook_events = Representation.new(self.with(path: "user/settings/webhooks/events"))
53
+ end
54
+ end
55
+ end