blob: e13aaf16732d85d87e25973afd5cf25c8982c6ce (
plain)
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
class GlobalMilestone
attr_accessor :title, :milestones
alias_attribute :name, :title
def self.build_collection(milestones)
milestones = milestones.group_by(&:title)
milestones.map do |title, milestones|
new(title, milestones)
end
end
def initialize(title, milestones)
@title = title
@milestones = milestones
end
def safe_title
@title.to_slug.normalize.to_s
end
def expired?
if due_date
due_date.past?
else
false
end
end
def projects
@projects ||= Project.for_milestones(milestones.map(&:id))
end
def issues_count
issues.count
end
def merge_requests_count
merge_requests.count
end
def open_items_count
opened_issues.count + opened_merge_requests.count
end
def closed_items_count
closed_issues.count + closed_merge_requests.count
end
def total_items_count
issues_count + merge_requests_count
end
def percent_complete
((closed_items_count * 100) / total_items_count).abs
rescue ZeroDivisionError
0
end
def state
state = milestones.map { |milestone| milestone.state }
if state.count('closed') == state.size
'closed'
else
'active'
end
end
def active?
state == 'active'
end
def closed?
state == 'closed'
end
def issues
@issues ||= Issue.of_milestones(milestones.map(&:id)).includes(:project)
end
def merge_requests
@merge_requests ||= MergeRequest.of_milestones(milestones.map(&:id)).includes(:target_project)
end
def participants
@participants ||= milestones.map(&:participants).flatten.compact.uniq
end
def labels
@labels ||= milestones.map do |ms|
ms.labels.map { |label| LabelWithMilestone.new(label, ms) }
end.flatten.sort_by!(&:title)
end
def opened_issues
issues.opened
end
def closed_issues
issues.closed
end
def opened_merge_requests
merge_requests.opened
end
def closed_merge_requests
merge_requests.with_states(:closed, :merged, :locked)
end
def complete?
total_items_count == closed_items_count
end
def due_date
return @due_date if defined?(@due_date)
@due_date =
if @milestones.all? { |x| x.due_date == @milestones.first.due_date }
@milestones.first.due_date
else
nil
end
end
def expires_at
if due_date
if due_date.past?
"expired on #{due_date.to_s(:medium)}"
else
"expires on #{due_date.to_s(:medium)}"
end
end
end
end
|