bloomy 0.3.0 → 0.5.4
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/.rubocop.yml +10 -30
- data/lib/bloomy/client.rb +9 -7
- data/lib/bloomy/operations/goals.rb +13 -12
- data/lib/bloomy/operations/headlines.rb +32 -18
- data/lib/bloomy/operations/issues.rb +36 -16
- data/lib/bloomy/operations/meetings.rb +10 -8
- data/lib/bloomy/operations/scorecard.rb +16 -12
- data/lib/bloomy/operations/todos.rb +62 -13
- data/lib/bloomy/operations/users.rb +8 -19
- data/lib/bloomy/utils/get_user_id.rb +22 -0
- data/lib/bloomy/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5967a74a2cb5758a74e4877ab46a57eeba59f85a023039c1252d47087007bfd7
|
4
|
+
data.tar.gz: 6ded65188a434b4a3fa47cb9007b5c1e10e97b88266c6442e4e74684b7f7f552
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5eaeb394ba3edbd99e433ab9760f510a9a0e219c5b0de8cf2fe3ef0cac7a03a12fbf3325515e3485629186d600724e7e8001d32070baf400a23b9453fd64476
|
7
|
+
data.tar.gz: 9298429c7361153eb4f58e35604defb752362add6f43bb253413c21abe11e2ae4f6d4997c03df337e2f12dcc8097685333ab68c7f0b12656b8f3594804f773fa
|
data/.rubocop.yml
CHANGED
@@ -1,30 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
Metrics/BlockLength:
|
12
|
-
Enabled: false
|
13
|
-
|
14
|
-
Metrics/CyclomaticComplexity:
|
15
|
-
Enabled: false
|
16
|
-
|
17
|
-
Metrics/MethodLength:
|
18
|
-
Enabled: false
|
19
|
-
|
20
|
-
Metrics/PerceivedComplexity:
|
21
|
-
Enabled: false
|
22
|
-
|
23
|
-
Naming/AccessorMethodName:
|
24
|
-
Enabled: false
|
25
|
-
|
26
|
-
Gemspec/DevelopmentDependencies:
|
27
|
-
Enabled: false
|
28
|
-
|
29
|
-
Style/StringLiterals:
|
30
|
-
EnforcedStyle: double_quotes
|
1
|
+
require:
|
2
|
+
- standard
|
3
|
+
- standard-custom
|
4
|
+
- standard-performance
|
5
|
+
- rubocop-performance
|
6
|
+
|
7
|
+
inherit_gem:
|
8
|
+
standard: config/base.yml
|
9
|
+
standard-custom: config/base.yml
|
10
|
+
standard-performance: config/base.yml
|
data/lib/bloomy/client.rb
CHANGED
@@ -25,6 +25,9 @@ module Bloomy
|
|
25
25
|
def initialize(api_key = nil)
|
26
26
|
@configuration = Configuration.new unless api_key
|
27
27
|
@api_key = api_key || @configuration.api_key
|
28
|
+
|
29
|
+
raise ArgumentError, "No API key provided. Set it in configuration or pass it directly." unless @api_key
|
30
|
+
|
28
31
|
@base_url = "https://app.bloomgrowth.com/api/v1"
|
29
32
|
@conn = Faraday.new(url: @base_url) do |faraday|
|
30
33
|
faraday.response :json
|
@@ -34,13 +37,12 @@ module Bloomy
|
|
34
37
|
faraday.headers["Authorization"] = "Bearer #{@api_key}"
|
35
38
|
end
|
36
39
|
@user = User.new(@conn)
|
37
|
-
@
|
38
|
-
@
|
39
|
-
@
|
40
|
-
@
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@headline = Headline.new(@conn, @user_id)
|
40
|
+
@todo = Todo.new(@conn)
|
41
|
+
@goal = Goal.new(@conn)
|
42
|
+
@meeting = Meeting.new(@conn)
|
43
|
+
@scorecard = Scorecard.new(@conn)
|
44
|
+
@issue = Issue.new(@conn)
|
45
|
+
@headline = Headline.new(@conn)
|
44
46
|
end
|
45
47
|
end
|
46
48
|
end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "bloomy/utils/get_user_id"
|
4
|
+
|
3
5
|
# Class to handle all the operations related to goals
|
4
6
|
class Goal
|
7
|
+
include Bloomy::Utilities::UserIdUtility
|
5
8
|
# Initializes a new Goal instance
|
6
9
|
#
|
7
10
|
# @param conn [Object] the connection object to interact with the API
|
8
|
-
|
9
|
-
def initialize(conn, user_id)
|
11
|
+
def initialize(conn)
|
10
12
|
@conn = conn
|
11
|
-
@user_id = user_id
|
12
13
|
end
|
13
14
|
|
14
15
|
# Lists all goals for a specific user
|
@@ -19,7 +20,7 @@ class Goal
|
|
19
20
|
# @example
|
20
21
|
# client.goal.list
|
21
22
|
# #=> [{ id: 1, title: "Complete project", created_at: "2024-06-10", ... }, ...]
|
22
|
-
def list(user_id
|
23
|
+
def list(user_id = self.user_id, archived: false)
|
23
24
|
active_goals = @conn.get("rocks/user/#{user_id}?include_origin=true").body.map do |goal|
|
24
25
|
{
|
25
26
|
id: goal["Id"],
|
@@ -28,11 +29,11 @@ class Goal
|
|
28
29
|
due_date: goal["DueDate"],
|
29
30
|
status: goal["Complete"] ? "Completed" : "Incomplete",
|
30
31
|
meeting_id: goal["Origins"].empty? ? nil : goal["Origins"][0]["Id"],
|
31
|
-
|
32
|
+
meeting_title: goal["Origins"].empty? ? nil : goal["Origins"][0]["Name"]
|
32
33
|
}
|
33
34
|
end
|
34
35
|
|
35
|
-
archived ? {active: active_goals, archived: get_archived_goals(user_id
|
36
|
+
archived ? {active: active_goals, archived: get_archived_goals(self.user_id)} : active_goals
|
36
37
|
end
|
37
38
|
|
38
39
|
# Creates a new goal
|
@@ -44,14 +45,14 @@ class Goal
|
|
44
45
|
# @example
|
45
46
|
# client.goal.create(title: "New Goal", meeting_id: 1)
|
46
47
|
# #=> { goal_id: 1, title: "New Goal", meeting_id: 1, ... }
|
47
|
-
def create(title:, meeting_id:, user_id:
|
48
|
+
def create(title:, meeting_id:, user_id: self.user_id)
|
48
49
|
payload = {title: title, accountableUserId: user_id}.to_json
|
49
50
|
response = @conn.post("/api/v1/L10/#{meeting_id}/rocks", payload).body
|
50
51
|
{
|
51
52
|
goal_id: response["Id"],
|
52
53
|
title: title,
|
53
54
|
meeting_id: meeting_id,
|
54
|
-
|
55
|
+
meeting_title: response["Origins"][0]["Name"],
|
55
56
|
user_id: user_id,
|
56
57
|
user_name: response["Owner"]["Name"],
|
57
58
|
created_at: DateTime.parse(response["CreateTime"])
|
@@ -67,7 +68,7 @@ class Goal
|
|
67
68
|
# #=> { status: 200 }
|
68
69
|
def delete(goal_id)
|
69
70
|
response = @conn.delete("/api/v1/rocks/#{goal_id}")
|
70
|
-
|
71
|
+
response.success?
|
71
72
|
end
|
72
73
|
|
73
74
|
# Updates a goal
|
@@ -79,10 +80,10 @@ class Goal
|
|
79
80
|
# @example
|
80
81
|
# client.goal.update(goal_id: 1, title: "Updated Goal")
|
81
82
|
# #=> { status: 200 }
|
82
|
-
def update(goal_id:, title:, accountable_user:
|
83
|
+
def update(goal_id:, title:, accountable_user: user_id)
|
83
84
|
payload = {title: title, accountableUserId: accountable_user}.to_json
|
84
85
|
response = @conn.put("/api/v1/rocks/#{goal_id}", payload)
|
85
|
-
|
86
|
+
response.success?
|
86
87
|
end
|
87
88
|
|
88
89
|
private
|
@@ -94,7 +95,7 @@ class Goal
|
|
94
95
|
# @example
|
95
96
|
# goal.send(:get_archived_goals)
|
96
97
|
# #=> [{ id: 1, title: "Archived Goal", created_at: "2024-06-10", ... }, ...]
|
97
|
-
def get_archived_goals(user_id
|
98
|
+
def get_archived_goals(user_id = self.user_id)
|
98
99
|
response = @conn.get("archivedrocks/user/#{user_id}").body
|
99
100
|
response.map do |goal|
|
100
101
|
{
|
@@ -1,23 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "bloomy/utils/get_user_id"
|
4
|
+
|
3
5
|
class Headline
|
6
|
+
include Bloomy::Utilities::UserIdUtility
|
4
7
|
# Initializes a new headline instance
|
5
8
|
#
|
6
9
|
# @param conn [Object] the connection object to interact with the API
|
7
|
-
|
8
|
-
def initialize(conn, user_id)
|
10
|
+
def initialize(conn)
|
9
11
|
@conn = conn
|
10
|
-
@user_id = user_id
|
11
12
|
end
|
12
13
|
|
13
14
|
# Creates a new headline
|
14
15
|
#
|
15
16
|
# @param meeting_id [Integer] the ID of the meeting
|
16
17
|
# @param title [String] the title of the headline
|
17
|
-
# @param owner_id [Integer] the ID of the owner
|
18
|
+
# @param owner_id [Integer] the ID of the headline owner
|
18
19
|
# @param notes [String] additional notes for the headline
|
19
20
|
# @return [Hash] the created headline details
|
20
|
-
def create(meeting_id, title, owner_id:
|
21
|
+
def create(meeting_id, title, owner_id: user_id, notes: nil)
|
21
22
|
response = @conn.post("/api/v1/L10/#{meeting_id}/headlines",
|
22
23
|
{title: title, ownerId: owner_id, notes: notes}.to_json)
|
23
24
|
raise "Failed to create headline" unless response.status == 200
|
@@ -26,7 +27,7 @@ class Headline
|
|
26
27
|
id: response.body["Id"],
|
27
28
|
title: response.body["Title"],
|
28
29
|
owner_id: response.body["OwnerId"],
|
29
|
-
|
30
|
+
notes_url: response.body["DetailsUrl"]
|
30
31
|
}
|
31
32
|
end
|
32
33
|
|
@@ -52,9 +53,10 @@ class Headline
|
|
52
53
|
{
|
53
54
|
id: response.body["Id"],
|
54
55
|
title: response.body["Name"],
|
56
|
+
notes_url: response.body["DetailsUrl"],
|
55
57
|
meeting_details: {
|
56
58
|
id: response.body["OriginId"],
|
57
|
-
|
59
|
+
title: response.body["Origin"]
|
58
60
|
},
|
59
61
|
owner_details: {
|
60
62
|
id: response.body["Owner"]["Id"],
|
@@ -66,20 +68,35 @@ class Headline
|
|
66
68
|
}
|
67
69
|
end
|
68
70
|
|
69
|
-
# Get user
|
71
|
+
# Get headlines for a user or a meeting.
|
70
72
|
#
|
71
|
-
# @param user_id [Integer] the ID of the user
|
72
|
-
# @
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
# @param user_id [Integer, nil] the ID of the user (defaults to initialized user_id)
|
74
|
+
# @param meeting_id [Integer, nil] the ID of the meeting
|
75
|
+
# @raise [ArgumentError] if both `user_id` and `meeting_id` are provided
|
76
|
+
# @return [Array<Hash>] the list of headlines
|
77
|
+
# @example
|
78
|
+
# # Fetch headlines for a user
|
79
|
+
# client.headline.list
|
80
|
+
# #=> [{ id: 1, title: "Headline Title", meeting_details: { id: 1, name: "Team Meeting" }, ... }, ...]
|
81
|
+
def list(user_id: nil, meeting_id: nil)
|
82
|
+
raise ArgumentError, "Please provide either `user_id` or `meeting_id`, not both." if user_id && meeting_id
|
83
|
+
|
84
|
+
if meeting_id
|
85
|
+
response = @conn.get("/api/v1/l10/#{meeting_id}/headlines")
|
86
|
+
else
|
87
|
+
user_id ||= self.user_id
|
88
|
+
response = @conn.get("/api/v1/headline/users/#{user_id}")
|
89
|
+
end
|
90
|
+
|
91
|
+
raise "Failed to list headlines" unless response.success?
|
92
|
+
|
76
93
|
response.body.map do |headline|
|
77
94
|
{
|
78
95
|
id: headline["Id"],
|
79
96
|
title: headline["Name"],
|
80
97
|
meeting_details: {
|
81
98
|
id: headline["OriginId"],
|
82
|
-
|
99
|
+
title: headline["Origin"]
|
83
100
|
},
|
84
101
|
owner_details: {
|
85
102
|
id: headline["Owner"]["Id"],
|
@@ -99,9 +116,6 @@ class Headline
|
|
99
116
|
# @return [Boolean] true if the deletion was successful
|
100
117
|
def delete(meeting_id, headline_id)
|
101
118
|
response = @conn.delete("/api/v1/L10/#{meeting_id}/headlines/#{headline_id}")
|
102
|
-
|
103
|
-
# Raise an issue if response.status != 200
|
104
|
-
raise "Failed to delete headline" unless response.status == 200
|
105
|
-
true
|
119
|
+
response.success?
|
106
120
|
end
|
107
121
|
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "json"
|
4
|
+
require "bloomy/utils/get_user_id"
|
4
5
|
|
5
6
|
# Class to handle all the operations related to issues
|
6
7
|
class Issue
|
8
|
+
include Bloomy::Utilities::UserIdUtility
|
7
9
|
# Initializes a new Issue instance
|
8
10
|
#
|
9
11
|
# @param conn [Object] the connection object to interact with the API
|
10
|
-
|
11
|
-
def initialize(conn, user_id)
|
12
|
+
def initialize(conn)
|
12
13
|
@conn = conn
|
13
|
-
@user_id = user_id
|
14
14
|
end
|
15
15
|
|
16
16
|
# Retrieves details of a specific issue
|
@@ -30,7 +30,7 @@ class Issue
|
|
30
30
|
completed_at: response["CloseTime"],
|
31
31
|
meeting_details: {
|
32
32
|
id: response["OriginId"],
|
33
|
-
|
33
|
+
title: response["Origin"]
|
34
34
|
},
|
35
35
|
owner_details: {
|
36
36
|
id: response["Owner"]["Id"],
|
@@ -39,15 +39,33 @@ class Issue
|
|
39
39
|
}
|
40
40
|
end
|
41
41
|
|
42
|
-
# Lists issues for a specific user
|
42
|
+
# Lists issues for a specific user or meeting
|
43
43
|
#
|
44
|
-
# @param user_id [Integer] the ID of the user (
|
44
|
+
# @param user_id [Integer, nil] the ID of the user (defaults to initialized user_id)
|
45
|
+
# @param meeting_id [Integer, nil] the ID of the meeting
|
46
|
+
# @raise [ArgumentError] if both `user_id` and `meeting_id` are provided
|
45
47
|
# @return [Array<Hash>] an array of hashes containing issues details
|
46
48
|
# @example
|
49
|
+
# # Fetch issues for the current user
|
47
50
|
# issue.list
|
48
|
-
#
|
49
|
-
|
50
|
-
|
51
|
+
#
|
52
|
+
# # Fetch issues for a specific user
|
53
|
+
# issue.list(user_id: 42)
|
54
|
+
#
|
55
|
+
# # Fetch issues for a specific meeting
|
56
|
+
# issue.list(meeting_id: 99)
|
57
|
+
def list(user_id: nil, meeting_id: nil)
|
58
|
+
if user_id && meeting_id
|
59
|
+
raise ArgumentError, "Please provide either `user_id` or `meeting_id`, not both."
|
60
|
+
end
|
61
|
+
|
62
|
+
if meeting_id
|
63
|
+
response = @conn.get("l10/#{meeting_id}/issues").body
|
64
|
+
else
|
65
|
+
user_id ||= self.user_id
|
66
|
+
response = @conn.get("issues/users/#{user_id}").body
|
67
|
+
end
|
68
|
+
|
51
69
|
response.map do |issue|
|
52
70
|
{
|
53
71
|
id: issue["Id"],
|
@@ -55,7 +73,7 @@ class Issue
|
|
55
73
|
notes_url: issue["DetailsUrl"],
|
56
74
|
created_at: issue["CreateTime"],
|
57
75
|
meeting_id: issue["OriginId"],
|
58
|
-
|
76
|
+
meeting_title: issue["Origin"]
|
59
77
|
}
|
60
78
|
end
|
61
79
|
end
|
@@ -68,19 +86,21 @@ class Issue
|
|
68
86
|
# issue.complete(123)
|
69
87
|
# #=> true
|
70
88
|
def complete(issue_id)
|
71
|
-
response = @conn.post("issues/#{issue_id}/complete", {complete: true}.to_json)
|
72
|
-
response
|
89
|
+
response = @conn.post("issues/#{issue_id}/complete", {complete: true}.to_json)
|
90
|
+
response.success?
|
73
91
|
end
|
74
92
|
|
75
93
|
# Creates a new issue
|
76
94
|
#
|
77
|
-
# @param title [String] the title of the new issue
|
78
95
|
# @param meeting_id [Integer] the ID of the meeting associated with the issue
|
96
|
+
# @param title [String] the title of the new issue
|
97
|
+
# @param user_id [Integer] the ID of the user responsible for the issue (default: initialized user ID)
|
98
|
+
# @param notes [String, nil] the notes for the issue (optional)
|
79
99
|
# @return [Hash] a hash containing the new issue's ID and title
|
80
100
|
# @example
|
81
|
-
# issue.create("New Issue"
|
101
|
+
# issue.create(meeting_id: 123, title: "New Issue")
|
82
102
|
# #=> { id: 789, title: "New Issue" }
|
83
|
-
def create(meeting_id:, title:, user_id:
|
103
|
+
def create(meeting_id:, title:, user_id: self.user_id, notes: nil)
|
84
104
|
response = @conn.post("issues/create", {title: title, meetingid: meeting_id, ownerid: user_id, notes: notes}.to_json)
|
85
105
|
{
|
86
106
|
id: response.body["Id"],
|
@@ -88,7 +108,7 @@ class Issue
|
|
88
108
|
meeting_title: response.body["Origin"],
|
89
109
|
title: response.body["Name"],
|
90
110
|
user_id: response.body["Owner"]["Id"],
|
91
|
-
|
111
|
+
notes_url: response.body["DetailsUrl"]
|
92
112
|
}
|
93
113
|
end
|
94
114
|
end
|
@@ -1,16 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "bloomy/utils/get_user_id"
|
4
|
+
|
3
5
|
# Class to handle all the operations related to meeting
|
4
6
|
# @note
|
5
7
|
# This class is already initialized via the client and usable as `client.measurable.method`
|
6
8
|
class Meeting
|
9
|
+
include Bloomy::Utilities::UserIdUtility
|
7
10
|
# Initializes a new Meeting instance
|
8
11
|
#
|
9
12
|
# @param conn [Object] the connection object to interact with the API
|
10
|
-
|
11
|
-
def initialize(conn, user_id)
|
13
|
+
def initialize(conn)
|
12
14
|
@conn = conn
|
13
|
-
@user_id = user_id
|
14
15
|
end
|
15
16
|
|
16
17
|
# Lists all meetings for a specific user
|
@@ -20,7 +21,7 @@ class Meeting
|
|
20
21
|
# @example
|
21
22
|
# client.meeting.list
|
22
23
|
# #=> [{ id: 123, name: "Team Meeting" }, ...]
|
23
|
-
def list(user_id
|
24
|
+
def list(user_id = self.user_id)
|
24
25
|
response = @conn.get("L10/#{user_id}/list").body
|
25
26
|
response.map { |meeting| {id: meeting["Id"], name: meeting["Name"]} }
|
26
27
|
end
|
@@ -99,7 +100,7 @@ class Meeting
|
|
99
100
|
response.map do |measurable|
|
100
101
|
{
|
101
102
|
id: measurable["Id"],
|
102
|
-
|
103
|
+
title: measurable["Name"].strip,
|
103
104
|
target: measurable["Target"],
|
104
105
|
operator: measurable["Direction"],
|
105
106
|
format: measurable["Modifiers"],
|
@@ -131,7 +132,7 @@ class Meeting
|
|
131
132
|
measurables = metrics(meeting_id)
|
132
133
|
{
|
133
134
|
id: meeting[:id],
|
134
|
-
|
135
|
+
title: meeting[:name],
|
135
136
|
attendees: attendees,
|
136
137
|
issues: issues,
|
137
138
|
todos: todos,
|
@@ -148,7 +149,7 @@ class Meeting
|
|
148
149
|
# @example
|
149
150
|
# client.meeting.create(title: "New Meeting", attendees: [2, 3])
|
150
151
|
# #=> { meeting_id: 1, title: "New Meeting", attendees: [2, 3] }
|
151
|
-
def create(title
|
152
|
+
def create(title, add_self: true, attendees: [])
|
152
153
|
payload = {title: title, addSelf: add_self}.to_json
|
153
154
|
response = @conn.post("L10/create", payload).body
|
154
155
|
meeting_id = response["meetingId"]
|
@@ -165,6 +166,7 @@ class Meeting
|
|
165
166
|
# @example
|
166
167
|
# client.meeting.delete(1)
|
167
168
|
def delete(meeting_id)
|
168
|
-
@conn.delete("L10/#{meeting_id}")
|
169
|
+
response = @conn.delete("L10/#{meeting_id}")
|
170
|
+
response.success?
|
169
171
|
end
|
170
172
|
end
|
@@ -1,18 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "json"
|
4
|
+
require "bloomy/utils/get_user_id"
|
4
5
|
|
5
6
|
# Class to handle all the operations related to scorecards
|
6
7
|
# @note
|
7
8
|
# This class is already initialized via the client and usable as `client.scorecard.method`
|
8
9
|
class Scorecard
|
10
|
+
include Bloomy::Utilities::UserIdUtility
|
11
|
+
|
9
12
|
# Initializes a new Scorecard instance
|
10
13
|
#
|
11
14
|
# @param conn [Object] the connection object to interact with the API
|
12
|
-
|
13
|
-
def initialize(conn, user_id)
|
15
|
+
def initialize(conn)
|
14
16
|
@conn = conn
|
15
|
-
@user_id = user_id
|
16
17
|
end
|
17
18
|
|
18
19
|
# Retrieves the current week details
|
@@ -48,15 +49,17 @@ class Scorecard
|
|
48
49
|
#
|
49
50
|
# # Fetch scorecards for a specific meeting
|
50
51
|
# client.scorecard.list(meeting_id: 99)
|
52
|
+
# @note
|
53
|
+
# The `week_offset` parameter is useful when fetching scores for previous or future weeks.
|
54
|
+
# For example, to fetch scores for the previous week, you can set `week_offset` to -1.
|
55
|
+
# To fetch scores for a future week, you can set `week_offset` to a positive value.
|
51
56
|
def list(user_id: nil, meeting_id: nil, show_empty: false, week_offset: nil)
|
52
|
-
if user_id && meeting_id
|
53
|
-
raise ArgumentError, "Please provide either `user_id` or `meeting_id`, not both."
|
54
|
-
end
|
57
|
+
raise ArgumentError, "Please provide either `user_id` or `meeting_id`, not both." if user_id && meeting_id
|
55
58
|
|
56
59
|
if meeting_id
|
57
60
|
response = @conn.get("scorecard/meeting/#{meeting_id}").body
|
58
61
|
else
|
59
|
-
user_id ||=
|
62
|
+
user_id ||= self.user_id
|
60
63
|
response = @conn.get("scorecard/user/#{user_id}").body
|
61
64
|
end
|
62
65
|
|
@@ -69,14 +72,15 @@ class Scorecard
|
|
69
72
|
target: scorecard["Target"],
|
70
73
|
value: scorecard["Measured"],
|
71
74
|
week: scorecard["Week"],
|
75
|
+
week_id: scorecard["ForWeek"],
|
72
76
|
updated_at: scorecard["DateEntered"]
|
73
77
|
}
|
74
78
|
end
|
75
79
|
|
76
80
|
if week_offset
|
77
81
|
week_data = current_week
|
78
|
-
week_id = week_data[:week_number]
|
79
|
-
scorecards.select! { |scorecard| scorecard[:
|
82
|
+
week_id = week_data[:week_number] + week_offset
|
83
|
+
scorecards.select! { |scorecard| scorecard[:week_id] == week_id }
|
80
84
|
end
|
81
85
|
|
82
86
|
scorecards.select! { |scorecard| scorecard[:value] || show_empty } unless show_empty
|
@@ -94,11 +98,11 @@ class Scorecard
|
|
94
98
|
# #=> true
|
95
99
|
# @note
|
96
100
|
# The `week_offset` parameter is useful when updating scores for previous weeks.
|
97
|
-
# For example, to update the score for the previous week, you can set `week_offset` to 1.
|
98
|
-
# To update a future week's score, you can set `week_offset` to a
|
101
|
+
# For example, to update the score for the previous week, you can set `week_offset` to -1.
|
102
|
+
# To update a future week's score, you can set `week_offset` to a positive value.
|
99
103
|
def score(measurable_id:, score:, week_offset: 0)
|
100
104
|
week_data = current_week
|
101
|
-
week_id = week_data[:week_number]
|
105
|
+
week_id = week_data[:week_number] + week_offset
|
102
106
|
|
103
107
|
response = @conn.put("measurables/#{measurable_id}/week/#{week_id}", {value: score}.to_json)
|
104
108
|
response.success?
|
@@ -1,31 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "date"
|
4
|
+
require_relative "../utils/get_user_id"
|
4
5
|
|
5
6
|
# Class to handle all the operations related to todos
|
6
7
|
class Todo
|
8
|
+
include Bloomy::Utilities::UserIdUtility
|
9
|
+
|
7
10
|
# Initializes a new Todo instance
|
8
11
|
#
|
9
12
|
# @param conn [Object] the connection object to interact with the API
|
10
|
-
|
11
|
-
def initialize(conn, user_id)
|
13
|
+
def initialize(conn)
|
12
14
|
@conn = conn
|
13
|
-
@user_id = user_id
|
14
15
|
end
|
15
16
|
|
16
|
-
# Lists all todos for a specific user
|
17
|
+
# Lists all todos for a specific user or meeting
|
17
18
|
#
|
18
|
-
# @param user_id [Integer] the ID of the user (default is the initialized user ID)
|
19
|
+
# @param user_id [Integer, nil] the ID of the user (default is the initialized user ID)
|
20
|
+
# @param meeting_id [Integer, nil] the ID of the meeting
|
19
21
|
# @return [Array<Hash>] an array of hashes containing todo details
|
22
|
+
# @raise [ArgumentError] if both `user_id` and `meeting_id` are provided
|
20
23
|
# @example
|
24
|
+
# # Fetch todos for the current user
|
21
25
|
# client.todo.list
|
22
|
-
# #=> [{ id: 1, title: "
|
23
|
-
|
24
|
-
|
26
|
+
# #=> [{ id: 1, title: "New Todo", due_date: "2024-06-15", ... }]
|
27
|
+
#
|
28
|
+
# # Fetch todos for a specific user
|
29
|
+
# client.todo.list(user_id: 42)
|
30
|
+
# # => [{ id: 1, title: "New Todo", due_date: "2024-06-15", ... }]
|
31
|
+
#
|
32
|
+
# # Fetch todos for a specific meeting
|
33
|
+
# client.todo.list(meeting_id: 99)
|
34
|
+
# # => [{ id: 1, title: "New Todo", due_date: "2024-06-15", ... }]
|
35
|
+
def list(user_id: nil, meeting_id: nil)
|
36
|
+
raise ArgumentError, "Please provide either `user_id` or `meeting_id`, not both." if user_id && meeting_id
|
37
|
+
|
38
|
+
if meeting_id
|
39
|
+
response = @conn.get("l10/#{meeting_id}/todos").body
|
40
|
+
else
|
41
|
+
user_id ||= self.user_id
|
42
|
+
response = @conn.get("todo/user/#{user_id}").body
|
43
|
+
end
|
44
|
+
|
25
45
|
response.map do |todo|
|
26
46
|
{
|
27
47
|
id: todo["Id"],
|
28
48
|
title: todo["Name"],
|
49
|
+
notes_url: todo["DetailsUrl"],
|
29
50
|
due_date: todo["DueDate"],
|
30
51
|
created_at: todo["CreateTime"],
|
31
52
|
completed_at: todo["CompleteTime"],
|
@@ -40,21 +61,23 @@ class Todo
|
|
40
61
|
# @param meeting_id [Integer] the ID of the meeting associated with the todo
|
41
62
|
# @param due_date [String, nil] the due date of the todo (optional)
|
42
63
|
# @param user_id [Integer] the ID of the user responsible for the todo (default: initialized user ID)
|
64
|
+
# @param notes [String, nil] additional notes for the todo (optional)
|
43
65
|
# @return [Hash] a hash containing the new todo's details
|
44
66
|
# @example
|
45
67
|
# client.todo.create(title: "New Todo", meeting_id: 1, due_date: "2024-06-15")
|
46
68
|
# #=> { id: 1, title: "New Todo", meeting_name: "Team Meeting", ... }
|
47
|
-
def create(title:, meeting_id:, due_date: nil, user_id:
|
48
|
-
payload = {title: title, accountableUserId: user_id}
|
69
|
+
def create(title:, meeting_id:, due_date: nil, user_id: self.user_id, notes: nil)
|
70
|
+
payload = {title: title, accountableUserId: user_id, notes: notes}
|
49
71
|
payload[:dueDate] = due_date if due_date
|
50
72
|
response = @conn.post("/api/v1/L10/#{meeting_id}/todos", payload.to_json).body
|
51
73
|
|
52
74
|
{
|
53
75
|
id: response["Id"],
|
54
76
|
title: response["Name"],
|
55
|
-
|
77
|
+
meeting_title: response["Origin"],
|
56
78
|
meeting_id: response["OriginId"],
|
57
|
-
due_date: response["DueDate"]
|
79
|
+
due_date: response["DueDate"],
|
80
|
+
notes_url: response["DetailsUrl"]
|
58
81
|
}
|
59
82
|
end
|
60
83
|
|
@@ -67,7 +90,7 @@ class Todo
|
|
67
90
|
# #=> { status: 200 }
|
68
91
|
def complete(todo_id)
|
69
92
|
response = @conn.post("/api/v1/todo/#{todo_id}/complete?status=true")
|
70
|
-
|
93
|
+
response.success?
|
71
94
|
end
|
72
95
|
|
73
96
|
# Updates an existing todo
|
@@ -96,4 +119,30 @@ class Todo
|
|
96
119
|
updated_at: DateTime.now.to_s
|
97
120
|
}
|
98
121
|
end
|
122
|
+
|
123
|
+
# Retrieves the details of a specific todo item by its ID.
|
124
|
+
#
|
125
|
+
# @param todo_id [String] The ID of the todo item to retrieve.
|
126
|
+
# @return [Hash] A hash containing the details of the todo item.
|
127
|
+
# @raise [RuntimeError] If the request to retrieve the todo details fails.
|
128
|
+
# @example
|
129
|
+
# client.todo.details(1)
|
130
|
+
# #=> { id: 1, title: "Updated Todo", due_date: "2024-11-01T01:41:41.528Z", ... }
|
131
|
+
def details(todo_id)
|
132
|
+
response = @conn.get("/api/v1/todo/#{todo_id}")
|
133
|
+
raise "Failed to get todo details. Status: #{response.status}" unless response.success?
|
134
|
+
|
135
|
+
todo = response.body
|
136
|
+
{
|
137
|
+
id: todo["Id"],
|
138
|
+
meeting_id: todo["OriginId"],
|
139
|
+
meeting_title: todo["Origin"],
|
140
|
+
title: todo["Name"],
|
141
|
+
notes_url: todo["DetailsUrl"],
|
142
|
+
due_date: todo["DueDate"],
|
143
|
+
created_at: todo["CreateTime"],
|
144
|
+
completed_at: todo["CompleteTime"],
|
145
|
+
status: todo["Complete"] ? "Complete" : "Incomplete"
|
146
|
+
}
|
147
|
+
end
|
99
148
|
end
|
@@ -1,26 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "bloomy/utils/get_user_id"
|
4
|
+
|
3
5
|
# Class to handle all the operations related to users
|
4
6
|
class User
|
5
|
-
|
7
|
+
include Bloomy::Utilities::UserIdUtility
|
6
8
|
|
7
9
|
# Initializes a new User instance
|
8
10
|
#
|
9
11
|
# @param conn [Object] the connection object to interact with the API
|
10
12
|
def initialize(conn)
|
11
13
|
@conn = conn
|
12
|
-
@default_user_id = current_user_id
|
13
|
-
end
|
14
|
-
|
15
|
-
# Retrieves the current user's ID
|
16
|
-
#
|
17
|
-
# @return [Integer] the ID of the current user
|
18
|
-
# @example
|
19
|
-
# client.user.current_user_id
|
20
|
-
# #=> 1
|
21
|
-
def current_user_id
|
22
|
-
response = @conn.get("users/mine").body
|
23
|
-
response["Id"]
|
24
14
|
end
|
25
15
|
|
26
16
|
# Retrieves details of a specific user
|
@@ -33,13 +23,12 @@ class User
|
|
33
23
|
# @example
|
34
24
|
# client.user.details
|
35
25
|
# #=> {name: "John Doe", id: 1, image_url: "http://example.com/image.jpg", ...}
|
36
|
-
def details(user_id
|
26
|
+
def details(user_id = self.user_id, direct_reports: false, positions: false, all: false)
|
37
27
|
response = @conn.get("users/#{user_id}").body
|
38
28
|
user_details = {name: response["Name"], id: response["Id"], image_url: response["ImageUrl"]}
|
39
29
|
|
40
|
-
user_details[:direct_reports] = direct_reports(user_id
|
41
|
-
user_details[:positions] = positions(user_id
|
42
|
-
|
30
|
+
user_details[:direct_reports] = direct_reports(user_id) if direct_reports || all
|
31
|
+
user_details[:positions] = positions(user_id) if positions || all
|
43
32
|
user_details
|
44
33
|
end
|
45
34
|
|
@@ -50,7 +39,7 @@ class User
|
|
50
39
|
# @example
|
51
40
|
# client.user.direct_reports
|
52
41
|
# #=> [{name: "Jane Smith", id: 2, image_url: "http://example.com/image.jpg"}, ...]
|
53
|
-
def direct_reports(user_id
|
42
|
+
def direct_reports(user_id = self.user_id)
|
54
43
|
direct_reports_response = @conn.get("users/#{user_id}/directreports").body
|
55
44
|
direct_reports_response.map { |report| {name: report["Name"], id: report["Id"], image_url: report["ImageUrl"]} }
|
56
45
|
end
|
@@ -62,7 +51,7 @@ class User
|
|
62
51
|
# @example
|
63
52
|
# user.positions
|
64
53
|
# #=> [{name: "Manager", id: 3}, ...]
|
65
|
-
def positions(user_id
|
54
|
+
def positions(user_id = self.user_id)
|
66
55
|
position_response = @conn.get("users/#{user_id}/seats").body
|
67
56
|
position_response.map do |position|
|
68
57
|
{name: position["Group"]["Position"]["Name"], id: position["Group"]["Position"]["Id"]}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Bloomy
|
2
|
+
module Utilities
|
3
|
+
module UserIdUtility
|
4
|
+
# Lazy loads the user_id of the default user
|
5
|
+
#
|
6
|
+
# @return [String] the user_id of the default user
|
7
|
+
def user_id
|
8
|
+
@user_id ||= default_user_id
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# Returns the user_id of the default user
|
14
|
+
#
|
15
|
+
# @return [String] The user_id of the default user
|
16
|
+
def default_user_id
|
17
|
+
response = @conn.get("users/mine").body
|
18
|
+
response["Id"]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/bloomy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bloomy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Franccesco Orozco
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- lib/bloomy/operations/scorecard.rb
|
65
65
|
- lib/bloomy/operations/todos.rb
|
66
66
|
- lib/bloomy/operations/users.rb
|
67
|
+
- lib/bloomy/utils/get_user_id.rb
|
67
68
|
- lib/bloomy/version.rb
|
68
69
|
- sig/bloomy.rbs
|
69
70
|
homepage: https://github.com/franccesco/bloomy
|