checkoff 0.128.0 → 0.130.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/GLOSSARY.md +7 -2
- data/Gemfile.lock +1 -1
- data/config/definitions.rb +7 -0
- data/lib/checkoff/internal/project_timing.rb +80 -0
- data/lib/checkoff/internal/selector_classes/project.rb +16 -0
- data/lib/checkoff/monkeypatches/resource_marshalling.rb +43 -0
- data/lib/checkoff/portfolios.rb +1 -1
- data/lib/checkoff/projects.rb +37 -1
- data/lib/checkoff/tasks.rb +1 -1
- data/lib/checkoff/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 671e124a1d07f8449c10381cdaf97619ae58cd56dda7adcf2672396c8cae1c07
|
4
|
+
data.tar.gz: fd7c3e0b5f1dd48e7a6281a807c92a7f6d7614d8d71e27bdf45895e1f98246d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee30df69be122ddcc9cfe7cfe5a72bab8ab53df71ddc0abbd81cab05767f25cea01047f2da2c6652831c4b5558ca23e126f02a0343c6f9963166c8047b93a634
|
7
|
+
data.tar.gz: 85e37bfc18623f783b70ab4724d1b19e3bfdf27c67c130e9c3a23d8b85faf938bdac54f15210d9b073641ec2d7fdcdca0b0a41630e4b660edb3b973c7c2a75ea
|
data/GLOSSARY.md
CHANGED
@@ -2,10 +2,15 @@
|
|
2
2
|
|
3
3
|
* ready: See tasks.rb#task_ready?. Indicates a task is ready for
|
4
4
|
a person to work on it. This is subtly different than what is used
|
5
|
-
by Asana to mark a date as red/green!
|
6
|
-
|
5
|
+
by Asana to mark a date as red/green!
|
6
|
+
|
7
|
+
A task is ready if it is not dependent on an incomplete task and one
|
8
|
+
of these is true:
|
7
9
|
|
8
10
|
* start is null and due on is today
|
9
11
|
* start is null and due at is before now
|
10
12
|
* start on is today
|
11
13
|
* start at is before now
|
14
|
+
|
15
|
+
A project is ready if there is no start date, or if the start date
|
16
|
+
is today or in the past.
|
data/Gemfile.lock
CHANGED
data/config/definitions.rb
CHANGED
@@ -209,6 +209,13 @@
|
|
209
209
|
#
|
210
210
|
# # @return [Asana::Resources::Portfolio,nil]
|
211
211
|
# def find_by_id(client, id, options: {}); end
|
212
|
+
# # Get portfolio items
|
213
|
+
# #
|
214
|
+
# # @param portfolio_gid [String] (required) Globally unique identifier for the portfolio.
|
215
|
+
# # @param options [Hash] the request I/O options
|
216
|
+
# #
|
217
|
+
# # @return [Enumerable<Asana::Resources::Project>]
|
218
|
+
# def get_items_for_portfolio(portfolio_gid: required("portfolio_gid"), options: {}); end
|
212
219
|
# end
|
213
220
|
# class User
|
214
221
|
# # Returns the full user record for the currently authenticated user.
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Checkoff
|
4
|
+
module Internal
|
5
|
+
# Utility methods for working with project dates and times
|
6
|
+
class ProjectTiming
|
7
|
+
# @param time_class [Class<Time>]
|
8
|
+
# @param date_class [Class<Date>]
|
9
|
+
# @param client [Asana::Client]
|
10
|
+
# @param custom_fields [Checkoff::CustomFields]
|
11
|
+
def initialize(time_class: Time, date_class: Date,
|
12
|
+
client: Checkoff::Clients.new.client,
|
13
|
+
custom_fields: Checkoff::CustomFields.new(client: client))
|
14
|
+
@time_class = time_class
|
15
|
+
@date_class = date_class
|
16
|
+
@custom_fields = custom_fields
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param project [Asana::Resources::Project]
|
20
|
+
# @param field_name [Symbol]
|
21
|
+
#
|
22
|
+
# @sg-ignore
|
23
|
+
# @return [Date, nil]
|
24
|
+
def start_date(project)
|
25
|
+
return @date_class.parse(project.start_on) unless project.start_on.nil?
|
26
|
+
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param project [Asana::Resources::Project]
|
31
|
+
# @param field_name [Symbol]
|
32
|
+
#
|
33
|
+
# @sg-ignore
|
34
|
+
# @return [Date, nil]
|
35
|
+
def due_date(project)
|
36
|
+
return @date_class.parse(project.due_on) unless project.due_on.nil?
|
37
|
+
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param project [Asana::Resources::Project]
|
42
|
+
# @param custom_field_name [String]
|
43
|
+
#
|
44
|
+
# @return [Time, Date, nil]
|
45
|
+
def custom_field(project, custom_field_name)
|
46
|
+
custom_field = @custom_fields.resource_custom_field_by_name_or_raise(project, custom_field_name)
|
47
|
+
# @sg-ignore
|
48
|
+
# @type [String, nil]
|
49
|
+
time_str = custom_field.fetch('display_value')
|
50
|
+
return nil if time_str.nil?
|
51
|
+
|
52
|
+
Time.parse(time_str)
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param project [Asana::Resources::Project]
|
56
|
+
# @param field_name [Symbol,Array]
|
57
|
+
#
|
58
|
+
# @sg-ignore
|
59
|
+
# @return [Date, Time, nil]
|
60
|
+
def date_or_time_field_by_name(project, field_name)
|
61
|
+
return due_date(project) if field_name == :due
|
62
|
+
|
63
|
+
return start_date(project) if field_name == :start
|
64
|
+
|
65
|
+
return start_date(project) if field_name == :ready
|
66
|
+
|
67
|
+
if field_name.is_a?(Array)
|
68
|
+
# @sg-ignore
|
69
|
+
# @type [Symbol]
|
70
|
+
actual_field_name = field_name.first
|
71
|
+
args = field_name[1..]
|
72
|
+
|
73
|
+
return custom_field(project, *args) if actual_field_name == :custom_field
|
74
|
+
end
|
75
|
+
|
76
|
+
raise "Teach me how to handle field #{field_name}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -20,6 +20,22 @@ module Checkoff
|
|
20
20
|
resource.due_date
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
# :ready? function
|
25
|
+
class ReadyPFunctionEvaluator < FunctionEvaluator
|
26
|
+
FUNCTION_NAME = :ready?
|
27
|
+
|
28
|
+
def matches?
|
29
|
+
fn?(selector, FUNCTION_NAME)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param project [Asana::Resources::Project]
|
33
|
+
# @param period [Symbol<:now_or_before,:this_week>]
|
34
|
+
# @return [Boolean]
|
35
|
+
def evaluate(project, period = :now_or_before)
|
36
|
+
@projects.project_ready?(project, period: period)
|
37
|
+
end
|
38
|
+
end
|
23
39
|
end
|
24
40
|
end
|
25
41
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'asana'
|
4
|
+
|
5
|
+
# Monkeypatches Asana::Resources::Resource so that Ruby marshalling and
|
6
|
+
# unmarshalling works on Asana resource classes. Currently, it will
|
7
|
+
# work unless you call an accessor method, which triggers Asana's
|
8
|
+
# client library Resource class' method_missing() to "cache" the
|
9
|
+
# result by creating a singleton method. Unfortunately, singleton
|
10
|
+
# methods break marshalling, which is not smart enough to know that it
|
11
|
+
# is not necessary to marshall them as they will simply be recreated
|
12
|
+
# when needed.
|
13
|
+
|
14
|
+
module Asana
|
15
|
+
# Monkeypatches:
|
16
|
+
#
|
17
|
+
# https://github.com/Asana/ruby-asana/blob/master/lib/asana
|
18
|
+
module Resources
|
19
|
+
# Public: The base resource class which provides some sugar over common
|
20
|
+
# resource functionality.
|
21
|
+
class Resource
|
22
|
+
# @return [Hash]
|
23
|
+
def marshal_dump
|
24
|
+
{ 'data' => @_data }
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param data [Hash]
|
28
|
+
#
|
29
|
+
# @return [void]
|
30
|
+
def marshal_load(data)
|
31
|
+
# @sg-ignore
|
32
|
+
# @type [Hash]
|
33
|
+
@_data = data.fetch('data')
|
34
|
+
@_data.each do |k, v|
|
35
|
+
if respond_to?(k)
|
36
|
+
variable = :"@#{k}"
|
37
|
+
instance_variable_set(variable, v)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/checkoff/portfolios.rb
CHANGED
data/lib/checkoff/projects.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative 'internal/config_loader'
|
4
4
|
require_relative 'internal/project_hashes'
|
5
|
+
require_relative 'internal/project_timing'
|
5
6
|
require_relative 'workspaces'
|
6
7
|
require_relative 'clients'
|
7
8
|
require 'cache_method'
|
@@ -32,15 +33,21 @@ module Checkoff
|
|
32
33
|
# @param client [Asana::Client]
|
33
34
|
# @param workspaces [Checkoff::Workspaces]
|
34
35
|
# @param project_hashes [Checkoff::Internal::ProjectHashes]
|
36
|
+
# @param project_timing [Checkoff::Internal::ProjectTiming]
|
37
|
+
# @param timing [Checkoff::Timing]
|
35
38
|
def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
|
36
39
|
client: Checkoff::Clients.new(config: config).client,
|
37
40
|
workspaces: Checkoff::Workspaces.new(config: config,
|
38
41
|
client: client),
|
39
|
-
project_hashes: Checkoff::Internal::ProjectHashes.new
|
42
|
+
project_hashes: Checkoff::Internal::ProjectHashes.new,
|
43
|
+
project_timing: Checkoff::Internal::ProjectTiming.new(client: client),
|
44
|
+
timing: Checkoff::Timing.new)
|
40
45
|
@config = config
|
41
46
|
@workspaces = workspaces
|
42
47
|
@client = client
|
43
48
|
@project_hashes = project_hashes
|
49
|
+
@project_timing = project_timing
|
50
|
+
@timing = timing
|
44
51
|
end
|
45
52
|
|
46
53
|
# Default options used in Asana API to pull tasks
|
@@ -139,8 +146,37 @@ module Checkoff
|
|
139
146
|
project_hashes.project_to_h(project_obj, project: project)
|
140
147
|
end
|
141
148
|
|
149
|
+
# Indicates a project is ready for a person to work on it. This
|
150
|
+
# is subtly different than what is used by Asana to mark a date as
|
151
|
+
# red/green!
|
152
|
+
#
|
153
|
+
# A project is ready if there is no start date, or if the start
|
154
|
+
# date is today or in the past.
|
155
|
+
#
|
156
|
+
# @param project [Asana::Resources::Project]
|
157
|
+
# @param period [Symbol<:now_or_before,:this_week>]
|
158
|
+
def project_ready?(project, period: :now_or_before)
|
159
|
+
in_period?(project, :ready, period)
|
160
|
+
end
|
161
|
+
|
162
|
+
# @param project [Asana::Resources::Project]
|
163
|
+
# @param field_name [Symbol,Array]
|
164
|
+
# @param period [Symbol<:now_or_before,:this_week>,Array] See Checkoff::Timing#in_period?
|
165
|
+
def in_period?(project, field_name, period)
|
166
|
+
# @type [Date,Time,nil]
|
167
|
+
project_date = project_timing.date_or_time_field_by_name(project, field_name)
|
168
|
+
|
169
|
+
timing.in_period?(project_date, period)
|
170
|
+
end
|
171
|
+
|
142
172
|
private
|
143
173
|
|
174
|
+
# @return [Checkoff::Timing]
|
175
|
+
attr_reader :timing
|
176
|
+
|
177
|
+
# @return [Checkoff::Internal::ProjectTiming]
|
178
|
+
attr_reader :project_timing
|
179
|
+
|
144
180
|
# @return [Checkoff::Internal::ProjectHashes]
|
145
181
|
attr_reader :project_hashes
|
146
182
|
|
data/lib/checkoff/tasks.rb
CHANGED
@@ -54,7 +54,7 @@ module Checkoff
|
|
54
54
|
@portfolios = portfolios
|
55
55
|
@custom_fields = custom_fields
|
56
56
|
@workspaces = workspaces
|
57
|
-
@timing = Timing.new(today_getter: date_class, now_getter: time_class)
|
57
|
+
@timing = Checkoff::Timing.new(today_getter: date_class, now_getter: time_class)
|
58
58
|
end
|
59
59
|
|
60
60
|
# Indicates a task is ready for a person to work on it. This is
|
data/lib/checkoff/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: checkoff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.130.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vince Broz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -135,6 +135,7 @@ files:
|
|
135
135
|
- lib/checkoff/internal/create-class.sh
|
136
136
|
- lib/checkoff/internal/project_hashes.rb
|
137
137
|
- lib/checkoff/internal/project_selector_evaluator.rb
|
138
|
+
- lib/checkoff/internal/project_timing.rb
|
138
139
|
- lib/checkoff/internal/search_url.rb
|
139
140
|
- lib/checkoff/internal/search_url/custom_field_param_converter.rb
|
140
141
|
- lib/checkoff/internal/search_url/custom_field_variant.rb
|
@@ -156,6 +157,7 @@ files:
|
|
156
157
|
- lib/checkoff/internal/task_hashes.rb
|
157
158
|
- lib/checkoff/internal/task_selector_evaluator.rb
|
158
159
|
- lib/checkoff/internal/task_timing.rb
|
160
|
+
- lib/checkoff/monkeypatches/resource_marshalling.rb
|
159
161
|
- lib/checkoff/my_tasks.rb
|
160
162
|
- lib/checkoff/portfolios.rb
|
161
163
|
- lib/checkoff/project_selectors.rb
|