-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathestimateTotalTime.omnifocusjs
122 lines (106 loc) · 3.27 KB
/
estimateTotalTime.omnifocusjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* global PlugIn Task Alert */
/* eslint spaced-comment: ["error", "always", { "exceptions": ["{"] }] */
/*{
"type": "action",
"targets": ["omnifocus"],
"author": "Kaitlin Salzke",
"identifier": "com.KaitlinSalzke.estimateTotalTime",
"version": "1.0.1",
"description": "Estimates the total time of the selected items",
"label": "Estimate Total Time",
"shortLabel": "Estimate Total Time",
"image": "deskclock.fill"
}*/
(() => {
const action = new PlugIn.Action(function (selection, sender) {
// build list of tasks to include
const tasksToInclude = new Set()
if (selection.projects.length > 0) {
selection.projects.forEach(project => {
project.flattenedChildren
.filter(task => !task.hasChildren && task.taskStatus !== Task.Status.Dropped && task.taskStatus !== Task.Status.Completed)
.forEach(task => tasksToInclude.add(task))
})
}
if (selection.tasks.length > 0) {
selection.tasks.forEach(task => tasksToInclude.add(task))
}
if (selection.tags.length > 0) {
selection.tags.forEach(tag => tag.remainingTasks.forEach(task => tasksToInclude.add(task)))
}
// find tasks with no estimate and calculate total time
const noEstimate = []
let totalTime = 0
tasksToInclude.forEach(task => {
if (task.estimatedMinutes === null) {
noEstimate.push(task.name)
}
totalTime += task.estimatedMinutes
})
// show details
showEstimatedTimes(totalTime, noEstimate)
})
action.validate = function (selection, sender) {
return selection.tasks.length > 0 || selection.projects.length > 0 || selection.tags.length > 0
}
return action
})()
function showEstimatedTimes (totalTime, tasksWithNoEstimate) {
const hours = Math.floor(totalTime / 60)
const minutes = totalTime % 60
// build string to show estimate of total time
const hoursUnit = (hours === 1) ? 'hour' : 'hours'
const minutesUnit = (minutes === 1) ? 'minute' : 'minutes'
let timeString
if (hours === 0) {
timeString = minutes + ' ' + minutesUnit
} else if (minutes === 0) {
timeString = hours + ' ' + hoursUnit
} else {
timeString =
hours + ' ' + hoursUnit + ' and ' + minutes + ' ' + minutesUnit
}
let warning
switch (tasksWithNoEstimate.length) {
case 0:
warning = ''
break
case 1:
warning =
'Note that the following task has no estimate: \u201C' +
tasksWithNoEstimate[0] +
'\u201D.'
break
case 2:
warning =
'Note that the following 2 tasks have no estimate: \u201C' +
tasksWithNoEstimate[0] +
'\u201D and \u201C' +
tasksWithNoEstimate[1] +
'\u201D.'
break
default:
warning =
'Note that the following ' +
tasksWithNoEstimate.length +
' tasks have no estimate: '
tasksWithNoEstimate.forEach(function (item, index, array) {
if (index !== 0) {
warning += ', '
}
if (index === array.length - 1) {
warning += 'and '
}
warning +=
'\u201C' +
item +
'\u201D'
if (index === array.length - 1) {
warning += '.'
}
})
}
// show result
const alert = new Alert('Estimated total time: ' + timeString + '.', warning)
alert.show()
}