plan_my_stuff 0.9.0 → 0.10.1
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/CHANGELOG.md +22 -0
- data/lib/plan_my_stuff/base_project.rb +4 -175
- data/lib/plan_my_stuff/base_project_extractions/graphql_hydration.rb +184 -0
- data/lib/plan_my_stuff/issue.rb +10 -1081
- data/lib/plan_my_stuff/issue_extractions/approvals.rb +370 -0
- data/lib/plan_my_stuff/issue_extractions/links.rb +525 -0
- data/lib/plan_my_stuff/issue_extractions/viewers.rb +75 -0
- data/lib/plan_my_stuff/issue_extractions/waiting.rb +148 -0
- data/lib/plan_my_stuff/version.rb +2 -2
- metadata +8 -6
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PlanMyStuff
|
|
4
|
+
module IssueExtractions
|
|
5
|
+
module Waiting
|
|
6
|
+
# Marks the issue as waiting on an end-user reply. Sets +metadata.waiting_on_user_at+ to now, (re)computes
|
|
7
|
+
# +metadata.next_reminder_at+, and adds the configured +waiting_on_user_label+ to the issue. Called from
|
|
8
|
+
# +Comment.create!+ when a support user posts a comment with +waiting_on_reply: true+, and from the
|
|
9
|
+
# +Issues::WaitingsController+ toggle.
|
|
10
|
+
#
|
|
11
|
+
# @param user [Object, nil] actor for the label notification event
|
|
12
|
+
#
|
|
13
|
+
# @return [self]
|
|
14
|
+
#
|
|
15
|
+
def enter_waiting_on_user!(user: nil)
|
|
16
|
+
now = Time.now.utc
|
|
17
|
+
label = PlanMyStuff.configuration.waiting_on_user_label
|
|
18
|
+
|
|
19
|
+
PlanMyStuff::Label.ensure!(repo: repo, name: label)
|
|
20
|
+
PlanMyStuff::Label.add!(issue: self, labels: [label], user: user) if labels.exclude?(label)
|
|
21
|
+
|
|
22
|
+
self.class.update!(
|
|
23
|
+
number: number,
|
|
24
|
+
repo: repo,
|
|
25
|
+
metadata: {
|
|
26
|
+
waiting_on_user_at: PlanMyStuff.format_time(now),
|
|
27
|
+
next_reminder_at: format_next_reminder_at(from: now),
|
|
28
|
+
},
|
|
29
|
+
)
|
|
30
|
+
reload
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Clears the waiting-on-user state: removes the label, clears +metadata.waiting_on_user_at+, and clears
|
|
34
|
+
# +metadata.next_reminder_at+ unless a waiting-on-approval timer is still active. No-ops if the issue is not
|
|
35
|
+
# currently waiting on a user reply.
|
|
36
|
+
#
|
|
37
|
+
# @return [self]
|
|
38
|
+
#
|
|
39
|
+
def clear_waiting_on_user!
|
|
40
|
+
label = PlanMyStuff.configuration.waiting_on_user_label
|
|
41
|
+
return self if metadata.waiting_on_user_at.nil? && labels.exclude?(label)
|
|
42
|
+
|
|
43
|
+
PlanMyStuff::Label.remove!(issue: self, labels: [label]) if labels.include?(label)
|
|
44
|
+
|
|
45
|
+
self.class.update!(
|
|
46
|
+
number: number,
|
|
47
|
+
repo: repo,
|
|
48
|
+
metadata: {
|
|
49
|
+
waiting_on_user_at: nil,
|
|
50
|
+
next_reminder_at:
|
|
51
|
+
metadata.waiting_on_approval_at ? PlanMyStuff.format_time(metadata.next_reminder_at) : nil,
|
|
52
|
+
},
|
|
53
|
+
)
|
|
54
|
+
reload
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Reopens an issue that was auto-closed by the inactivity sweep, clears +metadata.closed_by_inactivity+, and
|
|
58
|
+
# emits +plan_my_stuff.issue.reopened_by_reply+ carrying the reopening comment. Does not emit the regular
|
|
59
|
+
# +issue.reopened+ event \- subscribers that specifically care about this flow subscribe to the dedicated event.
|
|
60
|
+
#
|
|
61
|
+
# @param comment [PlanMyStuff::Comment] the reopening comment
|
|
62
|
+
# @param user [Object, nil] actor for the notification event
|
|
63
|
+
#
|
|
64
|
+
# @return [self]
|
|
65
|
+
#
|
|
66
|
+
def reopen_by_reply!(comment:, user: nil)
|
|
67
|
+
inactive_label = PlanMyStuff.configuration.user_inactive_label
|
|
68
|
+
PlanMyStuff::Label.remove!(issue: self, labels: [inactive_label]) if labels.include?(inactive_label)
|
|
69
|
+
|
|
70
|
+
self.class.update!(
|
|
71
|
+
number: number,
|
|
72
|
+
repo: repo,
|
|
73
|
+
state: :open,
|
|
74
|
+
metadata: { closed_by_inactivity: false },
|
|
75
|
+
)
|
|
76
|
+
reload
|
|
77
|
+
|
|
78
|
+
PlanMyStuff::Notifications.instrument(
|
|
79
|
+
'issue.reopened_by_reply',
|
|
80
|
+
self,
|
|
81
|
+
user: user,
|
|
82
|
+
comment: comment,
|
|
83
|
+
)
|
|
84
|
+
self
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
# Formats the next reminder time as an ISO 8601 UTC string, using per-issue +metadata.reminder_days+ when set
|
|
90
|
+
# or +config.reminder_days+ otherwise. Returns +nil+ when the effective schedule is empty.
|
|
91
|
+
#
|
|
92
|
+
# @param from [Time] baseline timestamp
|
|
93
|
+
#
|
|
94
|
+
# @return [String, nil]
|
|
95
|
+
#
|
|
96
|
+
def format_next_reminder_at(from:)
|
|
97
|
+
days = metadata.reminder_days.presence || PlanMyStuff.configuration.reminder_days
|
|
98
|
+
return if days.empty?
|
|
99
|
+
|
|
100
|
+
PlanMyStuff.format_time(from + days.first.days)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# When an issue is transitioning from open to closed, strips both waiting labels from the outgoing labels
|
|
104
|
+
# array and clears the waiting-related timestamps on +metadata+ so a single save writes both state change and
|
|
105
|
+
# cleanup. No-op for any other transition.
|
|
106
|
+
#
|
|
107
|
+
# @param attrs [Hash] the kwargs hash being assembled for +Issue.update!+; mutated in place
|
|
108
|
+
#
|
|
109
|
+
# @return [void]
|
|
110
|
+
#
|
|
111
|
+
def clear_waiting_state_on_close(attrs)
|
|
112
|
+
return unless state_changed?
|
|
113
|
+
return unless state_was == 'open'
|
|
114
|
+
return unless state == 'closed'
|
|
115
|
+
|
|
116
|
+
return if metadata.waiting_on_user_at.blank? && metadata.waiting_on_approval_at.blank?
|
|
117
|
+
|
|
118
|
+
waiting_labels = [
|
|
119
|
+
PlanMyStuff.configuration.waiting_on_user_label,
|
|
120
|
+
PlanMyStuff.configuration.waiting_on_approval_label,
|
|
121
|
+
]
|
|
122
|
+
attrs[:labels] = Array.wrap(attrs[:labels]) - waiting_labels
|
|
123
|
+
|
|
124
|
+
metadata.waiting_on_user_at = nil
|
|
125
|
+
metadata.waiting_on_approval_at = nil
|
|
126
|
+
metadata.next_reminder_at = nil
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# When an inactivity-closed issue is being reopened, strips the +user_inactive_label+ from the outgoing labels
|
|
130
|
+
# and clears +metadata.closed_by_inactivity+ so the save writes both. No-op for any other transition or for
|
|
131
|
+
# reopens of non-inactive closes.
|
|
132
|
+
#
|
|
133
|
+
# @param attrs [Hash] the kwargs hash being assembled for +Issue.update!+; mutated in place
|
|
134
|
+
#
|
|
135
|
+
# @return [void]
|
|
136
|
+
#
|
|
137
|
+
def clear_inactivity_state_on_reopen(attrs)
|
|
138
|
+
return unless state_changed?
|
|
139
|
+
return unless state_was == 'closed'
|
|
140
|
+
return unless state == 'open'
|
|
141
|
+
return unless metadata.closed_by_inactivity
|
|
142
|
+
|
|
143
|
+
attrs[:labels] = Array.wrap(attrs[:labels]) - [PlanMyStuff.configuration.user_inactive_label]
|
|
144
|
+
metadata.closed_by_inactivity = false
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: plan_my_stuff
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brands Insurance
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -44,7 +43,6 @@ dependencies:
|
|
|
44
43
|
- - "~>"
|
|
45
44
|
- !ruby/object:Gem::Version
|
|
46
45
|
version: 10.0.0
|
|
47
|
-
description:
|
|
48
46
|
email:
|
|
49
47
|
- documents@brandsinsurance.com
|
|
50
48
|
executables: []
|
|
@@ -113,6 +111,7 @@ files:
|
|
|
113
111
|
- lib/plan_my_stuff/aws_sns_simulator.rb
|
|
114
112
|
- lib/plan_my_stuff/base_metadata.rb
|
|
115
113
|
- lib/plan_my_stuff/base_project.rb
|
|
114
|
+
- lib/plan_my_stuff/base_project_extractions/graphql_hydration.rb
|
|
116
115
|
- lib/plan_my_stuff/base_project_item.rb
|
|
117
116
|
- lib/plan_my_stuff/base_project_metadata.rb
|
|
118
117
|
- lib/plan_my_stuff/cache.rb
|
|
@@ -125,6 +124,10 @@ files:
|
|
|
125
124
|
- lib/plan_my_stuff/errors.rb
|
|
126
125
|
- lib/plan_my_stuff/graphql/queries.rb
|
|
127
126
|
- lib/plan_my_stuff/issue.rb
|
|
127
|
+
- lib/plan_my_stuff/issue_extractions/approvals.rb
|
|
128
|
+
- lib/plan_my_stuff/issue_extractions/links.rb
|
|
129
|
+
- lib/plan_my_stuff/issue_extractions/viewers.rb
|
|
130
|
+
- lib/plan_my_stuff/issue_extractions/waiting.rb
|
|
128
131
|
- lib/plan_my_stuff/issue_metadata.rb
|
|
129
132
|
- lib/plan_my_stuff/label.rb
|
|
130
133
|
- lib/plan_my_stuff/link.rb
|
|
@@ -203,8 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
203
206
|
- !ruby/object:Gem::Version
|
|
204
207
|
version: '0'
|
|
205
208
|
requirements: []
|
|
206
|
-
rubygems_version:
|
|
207
|
-
signing_key:
|
|
209
|
+
rubygems_version: 4.0.6
|
|
208
210
|
specification_version: 4
|
|
209
211
|
summary: Shared PMS
|
|
210
212
|
test_files: []
|