jirametrics 2.8 → 2.11
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/lib/jirametrics/aggregate_config.rb +1 -1
- data/lib/jirametrics/aging_work_bar_chart.rb +7 -5
- data/lib/jirametrics/aging_work_in_progress_chart.rb +105 -41
- data/lib/jirametrics/aging_work_table.rb +50 -2
- data/lib/jirametrics/board.rb +32 -4
- data/lib/jirametrics/board_config.rb +6 -2
- data/lib/jirametrics/board_movement_calculator.rb +147 -0
- data/lib/jirametrics/change_item.rb +8 -1
- data/lib/jirametrics/chart_base.rb +40 -10
- data/lib/jirametrics/css_variable.rb +1 -1
- data/lib/jirametrics/cycletime_config.rb +10 -4
- data/lib/jirametrics/cycletime_histogram.rb +65 -2
- data/lib/jirametrics/data_quality_report.rb +53 -34
- data/lib/jirametrics/downloader.rb +0 -14
- data/lib/jirametrics/examples/standard_project.rb +2 -2
- data/lib/jirametrics/exporter.rb +10 -20
- data/lib/jirametrics/file_config.rb +21 -4
- data/lib/jirametrics/file_system.rb +23 -4
- data/lib/jirametrics/flow_efficiency_scatterplot.rb +1 -1
- data/lib/jirametrics/groupable_issue_chart.rb +1 -3
- data/lib/jirametrics/html/aging_work_bar_chart.erb +3 -12
- data/lib/jirametrics/html/aging_work_in_progress_chart.erb +22 -5
- data/lib/jirametrics/html/aging_work_table.erb +6 -4
- data/lib/jirametrics/html/cycletime_histogram.erb +74 -0
- data/lib/jirametrics/html/cycletime_scatterplot.erb +1 -10
- data/lib/jirametrics/html/daily_wip_chart.erb +1 -10
- data/lib/jirametrics/html/expedited_chart.erb +1 -10
- data/lib/jirametrics/html/hierarchy_table.erb +1 -1
- data/lib/jirametrics/html/index.css +11 -2
- data/lib/jirametrics/html/index.erb +8 -1
- data/lib/jirametrics/html/sprint_burndown.erb +1 -10
- data/lib/jirametrics/html/throughput_chart.erb +1 -10
- data/lib/jirametrics/html_report_config.rb +18 -23
- data/lib/jirametrics/issue.rb +77 -32
- data/lib/jirametrics/jira_gateway.rb +16 -3
- data/lib/jirametrics/project_config.rb +102 -45
- data/lib/jirametrics/status.rb +26 -7
- data/lib/jirametrics/status_collection.rb +69 -68
- data/lib/jirametrics/value_equality.rb +2 -2
- data/lib/jirametrics.rb +0 -1
- metadata +5 -9
- data/lib/jirametrics/discard_changes_before.rb +0 -37
|
@@ -38,22 +38,13 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
|
|
|
38
38
|
plugins: {
|
|
39
39
|
annotation: {
|
|
40
40
|
annotations: {
|
|
41
|
-
|
|
42
|
-
holiday<%= index %>: {
|
|
43
|
-
drawTime: 'beforeDraw',
|
|
44
|
-
type: 'box',
|
|
45
|
-
xMin: '<%= range.begin %>T00:00:00',
|
|
46
|
-
xMax: '<%= range.end %>T23:59:59',
|
|
47
|
-
backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
|
|
48
|
-
borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
|
|
49
|
-
},
|
|
50
|
-
<% end %>
|
|
41
|
+
<%= working_days_annotation %>
|
|
51
42
|
|
|
52
43
|
<% if percentage_line_x %>
|
|
53
44
|
line: {
|
|
54
45
|
type: 'line',
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
scaleID: 'x',
|
|
47
|
+
value: '<%= percentage_line_x %>',
|
|
57
48
|
borderColor: <%= CssVariable.new('--aging-work-bar-chart-percentage-line-color').to_json %>,
|
|
58
49
|
borderWidth: 1,
|
|
59
50
|
drawTime: 'afterDraw'
|
|
@@ -6,7 +6,7 @@ new Chart(document.getElementById(<%= chart_id.inspect %>).getContext('2d'),
|
|
|
6
6
|
{
|
|
7
7
|
type: 'bar',
|
|
8
8
|
data: {
|
|
9
|
-
labels: [<%=
|
|
9
|
+
labels: [<%= @board_columns.collect { |c| c.name.inspect }.join(',') %>],
|
|
10
10
|
datasets: <%= JSON.generate(data_sets) %>
|
|
11
11
|
},
|
|
12
12
|
options: {
|
|
@@ -22,8 +22,10 @@ new Chart(document.getElementById(<%= chart_id.inspect %>).getContext('2d'),
|
|
|
22
22
|
labelString: 'Date Completed'
|
|
23
23
|
},
|
|
24
24
|
grid: {
|
|
25
|
-
color: <%= CssVariable['--grid-line-color'].to_json
|
|
25
|
+
color: <%= CssVariable['--grid-line-color'].to_json %>,
|
|
26
|
+
z: 1 // draw the grid lines on top of the bars
|
|
26
27
|
},
|
|
28
|
+
stacked: true
|
|
27
29
|
},
|
|
28
30
|
y: {
|
|
29
31
|
scaleLabel: {
|
|
@@ -35,8 +37,11 @@ new Chart(document.getElementById(<%= chart_id.inspect %>).getContext('2d'),
|
|
|
35
37
|
text: 'Age in days'
|
|
36
38
|
},
|
|
37
39
|
grid: {
|
|
38
|
-
color: <%= CssVariable['--grid-line-color'].to_json
|
|
40
|
+
color: <%= CssVariable['--grid-line-color'].to_json %>,
|
|
41
|
+
z: 1 // draw the grid lines on top of the bars
|
|
39
42
|
},
|
|
43
|
+
stacked: true,
|
|
44
|
+
max: <%= (@max_age * 1.1).to_i %>
|
|
40
45
|
}
|
|
41
46
|
},
|
|
42
47
|
plugins: {
|
|
@@ -44,14 +49,26 @@ new Chart(document.getElementById(<%= chart_id.inspect %>).getContext('2d'),
|
|
|
44
49
|
callbacks: {
|
|
45
50
|
label: function(context) {
|
|
46
51
|
if( typeof(context.dataset.data[context.dataIndex]) == "number" ) {
|
|
47
|
-
|
|
52
|
+
let full_data = <%= @bar_data.inspect %>;
|
|
53
|
+
let columnIndex = context.dataIndex;
|
|
54
|
+
let rowIndex = context.datasetIndex - <%= @row_index_offset %>;
|
|
55
|
+
return context.dataset.label + " of completed work items left this column in " +full_data[rowIndex][columnIndex] + " days or less";
|
|
48
56
|
}
|
|
49
57
|
else {
|
|
50
|
-
return context.dataset.data[context.dataIndex].title
|
|
58
|
+
return context.dataset.data[context.dataIndex].title;
|
|
51
59
|
}
|
|
52
60
|
}
|
|
53
61
|
}
|
|
62
|
+
},
|
|
63
|
+
legend: {
|
|
64
|
+
labels: {
|
|
65
|
+
filter: function(item, chart) {
|
|
66
|
+
// Logic to remove a particular legend item goes here
|
|
67
|
+
return !item.text.includes('%');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
54
70
|
}
|
|
71
|
+
|
|
55
72
|
}
|
|
56
73
|
}
|
|
57
74
|
});
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<table class='standard'>
|
|
2
2
|
<thead>
|
|
3
3
|
<tr>
|
|
4
|
-
<th
|
|
5
|
-
<th>E</th>
|
|
6
|
-
<th>B</th>
|
|
4
|
+
<th title="Age in days">Age</th>
|
|
5
|
+
<th title="Expedited">E</th>
|
|
6
|
+
<th title="Blocked / Stalled">B/S</th>
|
|
7
7
|
<th>Issue</th>
|
|
8
8
|
<th>Status</th>
|
|
9
|
+
<th>Forecast</th>
|
|
9
10
|
<th>Fix versions</th>
|
|
10
11
|
<% if any_scrum_boards %>
|
|
11
12
|
<th>Sprints</th>
|
|
@@ -40,7 +41,8 @@
|
|
|
40
41
|
</div>
|
|
41
42
|
<% end %>
|
|
42
43
|
</td>
|
|
43
|
-
<td><%= format_status issue.status
|
|
44
|
+
<td><%= format_status issue.status, board: issue.board %></td>
|
|
45
|
+
<td><%= dates_text(issue) %></td>
|
|
44
46
|
<td><%= fix_versions_text(issue) %></td>
|
|
45
47
|
<% if any_scrum_boards %>
|
|
46
48
|
<td><%= sprints_text(issue) %></td>
|
|
@@ -1,6 +1,57 @@
|
|
|
1
1
|
<div class="chart">
|
|
2
2
|
<canvas id="<%= chart_id %>" width="<%= canvas_width %>" height="<%= canvas_height %>"></canvas>
|
|
3
3
|
</div>
|
|
4
|
+
<%
|
|
5
|
+
if show_stats
|
|
6
|
+
link_id = next_id
|
|
7
|
+
issues_id = next_id
|
|
8
|
+
%>
|
|
9
|
+
[<a id='<%= link_id %>' href="#" onclick='expand_collapse("<%= link_id %>", "<%= issues_id %>"); return false;'>Show details</a>]
|
|
10
|
+
<div id="<%= issues_id %>" style="display: none;">
|
|
11
|
+
<div>
|
|
12
|
+
<table class="standard">
|
|
13
|
+
<tr>
|
|
14
|
+
<th>Issue Type</th>
|
|
15
|
+
<th>Min</th>
|
|
16
|
+
<th>Max</th>
|
|
17
|
+
<th>Avg</th>
|
|
18
|
+
<th>Mode</th>
|
|
19
|
+
<% percentiles.each do |p| %>
|
|
20
|
+
<th><%= p %>th</th>
|
|
21
|
+
<% end %>
|
|
22
|
+
</tr>
|
|
23
|
+
<% the_stats.each do |k, v| %>
|
|
24
|
+
<tr>
|
|
25
|
+
<td><%= k %></td>
|
|
26
|
+
<td style="text-align: right;"><%= v[:min] %></td>
|
|
27
|
+
<td style="text-align: right;"><%= v[:max] %></td>
|
|
28
|
+
<td style="text-align: right;"><%= sprintf('%.2f', v[:average]) %></td>
|
|
29
|
+
<td><%= v[:mode].join(', ') %></td>
|
|
30
|
+
<% percentiles.each do |p| %>
|
|
31
|
+
<td style="text-align: right;"><%= v[:percentiles][p] %></td>
|
|
32
|
+
<% end %>
|
|
33
|
+
</tr>
|
|
34
|
+
<% end %>
|
|
35
|
+
</table>
|
|
36
|
+
</div>
|
|
37
|
+
<div>
|
|
38
|
+
<p>These statistics help understand the <i>"shape"</i> of the cycletime histogram distribution, to help us with predictions.</p>
|
|
39
|
+
<ul>
|
|
40
|
+
<li><b>Min & Max:</b> the observed spread for the data set. Useful to judge how wide the variation is. </li>
|
|
41
|
+
<li><b>Average:</b> the arithmetic mean of the data set. Useful as a <i>"typical representative"</i> of the complete set.</li>
|
|
42
|
+
<li><b>Mode:</b> the most repeated value(s) in the data set. This is the value we're most likely to remember. </li>
|
|
43
|
+
<li><b>Percentiles:</b> they partition the data set. If X is the Nth percentile, it means that N% of cycletime values are X or less. Typical percentiles of interest are:</li>
|
|
44
|
+
<ul>
|
|
45
|
+
<li><b>50%</b>: also known as the <b>Median</b>. Useful to establish short feedback loops, to monitor that it's not drifting to the right.</li>
|
|
46
|
+
<li><b>85%</b>: useful to establish service level expectations, accounting for rare events..</li>
|
|
47
|
+
<li><b>98% (or higher)</b>: useful to gauge worst case expectations..</li>
|
|
48
|
+
</ul>
|
|
49
|
+
</ul>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
<%
|
|
53
|
+
end
|
|
54
|
+
%>
|
|
4
55
|
<script>
|
|
5
56
|
new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
|
|
6
57
|
{
|
|
@@ -21,6 +72,8 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
|
|
|
21
72
|
grid: {
|
|
22
73
|
color: <%= CssVariable['--grid-line-color'].to_json %>
|
|
23
74
|
},
|
|
75
|
+
min: 0,
|
|
76
|
+
offset: false, // Gets rid of the ugly padding on left.
|
|
24
77
|
},
|
|
25
78
|
y: {
|
|
26
79
|
stacked: true,
|
|
@@ -34,6 +87,27 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
|
|
|
34
87
|
}
|
|
35
88
|
},
|
|
36
89
|
plugins: {
|
|
90
|
+
annotation: {
|
|
91
|
+
annotations: {
|
|
92
|
+
<%
|
|
93
|
+
results = the_stats[:all][:percentiles]
|
|
94
|
+
results.each do |percentile, value|
|
|
95
|
+
%>
|
|
96
|
+
percentile<%= percentile.to_s %>: {
|
|
97
|
+
type: 'line',
|
|
98
|
+
scaleID: 'x',
|
|
99
|
+
value: <%= value %>,
|
|
100
|
+
borderWidth: 1,
|
|
101
|
+
drawTime: 'beforeDatasetsDraw',
|
|
102
|
+
label: {
|
|
103
|
+
enabled: true,
|
|
104
|
+
content: '<%= "#{percentile}%" %>',
|
|
105
|
+
position: 'start',
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
<% end %>
|
|
109
|
+
},
|
|
110
|
+
},
|
|
37
111
|
tooltip: {
|
|
38
112
|
callbacks: {
|
|
39
113
|
label: function(context) {
|
|
@@ -53,16 +53,7 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
|
|
|
53
53
|
autocolors: false,
|
|
54
54
|
annotation: {
|
|
55
55
|
annotations: {
|
|
56
|
-
|
|
57
|
-
holiday<%= index %>: {
|
|
58
|
-
drawTime: 'beforeDraw',
|
|
59
|
-
type: 'box',
|
|
60
|
-
xMin: '<%= range.begin %>T00:00:00',
|
|
61
|
-
xMax: '<%= range.end %>T23:59:59',
|
|
62
|
-
backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
|
|
63
|
-
borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
|
|
64
|
-
},
|
|
65
|
-
<% end %>
|
|
56
|
+
<%= working_days_annotation %>
|
|
66
57
|
|
|
67
58
|
<% @percentage_lines.each_with_index do |args, index| %>
|
|
68
59
|
<% percent, color = args %>
|
|
@@ -50,16 +50,7 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'),
|
|
|
50
50
|
},
|
|
51
51
|
annotation: {
|
|
52
52
|
annotations: {
|
|
53
|
-
|
|
54
|
-
holiday<%= index %>: {
|
|
55
|
-
drawTime: 'beforeDraw',
|
|
56
|
-
type: 'box',
|
|
57
|
-
xMin: '<%= range.begin %>T00:00:00',
|
|
58
|
-
xMax: '<%= range.end %>T23:59:59',
|
|
59
|
-
backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
|
|
60
|
-
borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
|
|
61
|
-
},
|
|
62
|
-
<% end %>
|
|
53
|
+
<%= working_days_annotation %>
|
|
63
54
|
}
|
|
64
55
|
},
|
|
65
56
|
legend: {
|
|
@@ -55,16 +55,7 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
|
|
|
55
55
|
autocolors: false,
|
|
56
56
|
annotation: {
|
|
57
57
|
annotations: {
|
|
58
|
-
|
|
59
|
-
holiday<%= index %>: {
|
|
60
|
-
drawTime: 'beforeDraw',
|
|
61
|
-
type: 'box',
|
|
62
|
-
xMin: '<%= range.begin %>T00:00:00',
|
|
63
|
-
xMax: '<%= range.end %>T23:59:59',
|
|
64
|
-
backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
|
|
65
|
-
borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
|
|
66
|
-
},
|
|
67
|
-
<% end %>
|
|
58
|
+
<%= working_days_annotation %>
|
|
68
59
|
}
|
|
69
60
|
}
|
|
70
61
|
}
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
</span>
|
|
23
23
|
</td>
|
|
24
24
|
<td><span style="color: <%= color %>; font-style: italic;"><%= issue.summary[0..80] %></span></td>
|
|
25
|
-
<td><%= format_status issue.status
|
|
25
|
+
<td><%= format_status issue.status, board: issue.board %></td>
|
|
26
26
|
</tr>
|
|
27
27
|
<% end %>
|
|
28
28
|
</tbody>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
--body-background: white;
|
|
3
3
|
--default-text-color: black;
|
|
4
4
|
--grid-line-color: lightgray;
|
|
5
|
+
--warning-banner: yellow;
|
|
5
6
|
|
|
6
7
|
--cycletime-scatterplot-overall-trendline-color: gray;
|
|
7
8
|
|
|
@@ -27,8 +28,16 @@
|
|
|
27
28
|
--throughput_chart_total_line_color: gray;
|
|
28
29
|
|
|
29
30
|
--aging-work-in-progress-chart-shading-color: lightgray;
|
|
31
|
+
--aging-work-in-progress-chart-shading-50-color: #2E8BC0; // green;
|
|
32
|
+
--aging-work-in-progress-chart-shading-85-color: #ADD8E6; // yellow;
|
|
33
|
+
--aging-work-in-progress-chart-shading-98-color: #FF8A8A; // orange;
|
|
34
|
+
--aging-work-in-progress-chart-shading-100-color: #FF2E2E; // red;
|
|
35
|
+
|
|
30
36
|
--aging-work-in-progress-by-age-trend-line-color: gray;
|
|
31
37
|
|
|
38
|
+
--aging-work-table-date-in-jeopardy: yellow;
|
|
39
|
+
--aging-work-table-date-overdue: red;
|
|
40
|
+
|
|
32
41
|
--hierarchy-table-inactive-item-text-color: gray;
|
|
33
42
|
|
|
34
43
|
--wip-chart-completed-color: #00ff00;
|
|
@@ -135,6 +144,8 @@ ul.quality_report {
|
|
|
135
144
|
|
|
136
145
|
@media screen and (prefers-color-scheme: dark) {
|
|
137
146
|
:root {
|
|
147
|
+
--warning-banner: #9F2B00;
|
|
148
|
+
|
|
138
149
|
--non-working-days-color: #2f2f2f;
|
|
139
150
|
--type-story-color: #6fb86f;
|
|
140
151
|
--type-task-color: #0021b3;
|
|
@@ -150,8 +161,6 @@ ul.quality_report {
|
|
|
150
161
|
--dead-color: black;
|
|
151
162
|
--wip-chart-active-color: #2551c1;
|
|
152
163
|
|
|
153
|
-
--aging-work-in-progress-chart-shading-color: #b4b4b4;
|
|
154
|
-
|
|
155
164
|
--status-category-inprogress-color: #1c49bb;
|
|
156
165
|
|
|
157
166
|
--cycletime-scatterplot-overall-trendline-color: gray;
|
|
@@ -23,13 +23,20 @@
|
|
|
23
23
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
|
24
24
|
location.reload()
|
|
25
25
|
})
|
|
26
|
-
|
|
27
26
|
</script>
|
|
28
27
|
<style>
|
|
29
28
|
<%= css %>
|
|
30
29
|
</style>
|
|
30
|
+
<script type="text/javascript">
|
|
31
|
+
Chart.defaults.color = getComputedStyle(document.documentElement).getPropertyValue('--default-text-color');
|
|
32
|
+
</script>
|
|
31
33
|
</head>
|
|
32
34
|
<body>
|
|
35
|
+
<noscript>
|
|
36
|
+
<div style="padding: 1em; background: gray; color: white; font-size: 2em;">
|
|
37
|
+
Javascript is currently disabled and that means that almost all of the charts in this report won't render. If you'd loaded this from a folder on SharePoint then save it locally and load it again.
|
|
38
|
+
</div>
|
|
39
|
+
</noscript>
|
|
33
40
|
<%= "\n" + @sections.collect { |text, type| text if type == :header }.compact.join("\n\n") %>
|
|
34
41
|
<%= "\n" + @sections.collect { |text, type| text if type == :body }.compact.join("\n\n") %>
|
|
35
42
|
</body>
|
|
@@ -56,16 +56,7 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
|
|
|
56
56
|
},
|
|
57
57
|
annotation: {
|
|
58
58
|
annotations: {
|
|
59
|
-
|
|
60
|
-
holiday<%= index %>: {
|
|
61
|
-
drawTime: 'beforeDraw',
|
|
62
|
-
type: 'box',
|
|
63
|
-
xMin: '<%= range.begin %>T00:00:00',
|
|
64
|
-
xMax: '<%= range.end %>T23:59:59',
|
|
65
|
-
backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
|
|
66
|
-
borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
|
|
67
|
-
},
|
|
68
|
-
<% end %>
|
|
59
|
+
<%= working_days_annotation %>
|
|
69
60
|
}
|
|
70
61
|
}
|
|
71
62
|
}
|
|
@@ -52,16 +52,7 @@ new Chart(document.getElementById('<%= chart_id %>').getContext('2d'), {
|
|
|
52
52
|
},
|
|
53
53
|
annotation: {
|
|
54
54
|
annotations: {
|
|
55
|
-
|
|
56
|
-
holiday<%= index %>: {
|
|
57
|
-
drawTime: 'beforeDraw',
|
|
58
|
-
type: 'box',
|
|
59
|
-
xMin: '<%= range.begin %>T00:00:00',
|
|
60
|
-
xMax: '<%= range.end %>T23:59:59',
|
|
61
|
-
backgroundColor: <%= CssVariable.new('--non-working-days-color').to_json %>,
|
|
62
|
-
borderColor: <%= CssVariable.new('--non-working-days-color').to_json %>
|
|
63
|
-
},
|
|
64
|
-
<% end %>
|
|
55
|
+
<%= working_days_annotation %>
|
|
65
56
|
}
|
|
66
57
|
}
|
|
67
58
|
}
|
|
@@ -5,16 +5,15 @@ require 'jirametrics/self_or_issue_dispatcher'
|
|
|
5
5
|
|
|
6
6
|
class HtmlReportConfig
|
|
7
7
|
include SelfOrIssueDispatcher
|
|
8
|
-
include DiscardChangesBefore
|
|
9
8
|
|
|
10
|
-
attr_reader :file_config, :sections
|
|
9
|
+
attr_reader :file_config, :sections, :charts
|
|
11
10
|
|
|
12
11
|
def self.define_chart name:, classname:, deprecated_warning: nil, deprecated_date: nil
|
|
13
12
|
lines = []
|
|
14
13
|
lines << "def #{name} &block"
|
|
15
14
|
lines << ' block = ->(_) {} unless block'
|
|
16
15
|
if deprecated_warning
|
|
17
|
-
lines << " deprecated date: #{deprecated_date.inspect}, message: #{deprecated_warning.inspect}"
|
|
16
|
+
lines << " file_system.deprecated date: #{deprecated_date.inspect}, message: #{deprecated_warning.inspect}"
|
|
18
17
|
end
|
|
19
18
|
lines << " execute_chart #{classname}.new(block)"
|
|
20
19
|
lines << 'end'
|
|
@@ -43,14 +42,15 @@ class HtmlReportConfig
|
|
|
43
42
|
def initialize file_config:, block:
|
|
44
43
|
@file_config = file_config
|
|
45
44
|
@block = block
|
|
46
|
-
@sections = []
|
|
45
|
+
@sections = [] # Where we store the chunks of text that will be assembled into the HTML
|
|
46
|
+
@charts = [] # Where we store all the charts we executed so we can assert against them.
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def cycletime label = nil, &block
|
|
50
50
|
@file_config.project_config.all_boards.each_value do |board|
|
|
51
51
|
raise 'Multiple cycletimes not supported' if board.cycletime
|
|
52
52
|
|
|
53
|
-
board.cycletime = CycleTimeConfig.new(parent_config: self, label: label, block: block)
|
|
53
|
+
board.cycletime = CycleTimeConfig.new(parent_config: self, label: label, block: block, file_system: file_system)
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -64,7 +64,7 @@ class HtmlReportConfig
|
|
|
64
64
|
|
|
65
65
|
# The quality report has to be generated last because otherwise cycletime won't have been
|
|
66
66
|
# set. Then we have to rotate it to the first position so it's at the top of the report.
|
|
67
|
-
execute_chart DataQualityReport.new(
|
|
67
|
+
execute_chart DataQualityReport.new(file_config.project_config.discarded_changes_data)
|
|
68
68
|
@sections.rotate!(-1)
|
|
69
69
|
|
|
70
70
|
html create_footer
|
|
@@ -101,9 +101,8 @@ class HtmlReportConfig
|
|
|
101
101
|
base_css
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
-
def board_id id
|
|
105
|
-
@board_id = id
|
|
106
|
-
@board_id
|
|
104
|
+
def board_id id
|
|
105
|
+
@board_id = id
|
|
107
106
|
end
|
|
108
107
|
|
|
109
108
|
def timezone_offset
|
|
@@ -143,19 +142,6 @@ class HtmlReportConfig
|
|
|
143
142
|
end
|
|
144
143
|
end
|
|
145
144
|
|
|
146
|
-
def discard_changes_before_hook issues_cutoff_times
|
|
147
|
-
# raise 'Cycletime must be defined before using discard_changes_before' unless @cycletime
|
|
148
|
-
|
|
149
|
-
@original_issue_times = {}
|
|
150
|
-
issues_cutoff_times.each do |issue, cutoff_time|
|
|
151
|
-
started = issue.board.cycletime.started_stopped_times(issue).first
|
|
152
|
-
if started && started <= cutoff_time
|
|
153
|
-
# We only need to log this if data was discarded
|
|
154
|
-
@original_issue_times[issue] = { cutoff_time: cutoff_time, started_time: started }
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
|
|
159
145
|
def dependency_chart &block
|
|
160
146
|
execute_chart DependencyChart.new block
|
|
161
147
|
end
|
|
@@ -175,7 +161,7 @@ class HtmlReportConfig
|
|
|
175
161
|
chart.settings = settings
|
|
176
162
|
|
|
177
163
|
chart.all_boards = project_config.all_boards
|
|
178
|
-
chart.board_id = find_board_id
|
|
164
|
+
chart.board_id = find_board_id
|
|
179
165
|
chart.holiday_dates = project_config.exporter.holiday_dates
|
|
180
166
|
|
|
181
167
|
time_range = @file_config.project_config.time_range
|
|
@@ -184,6 +170,7 @@ class HtmlReportConfig
|
|
|
184
170
|
|
|
185
171
|
after_init_block&.call chart
|
|
186
172
|
|
|
173
|
+
@charts << chart
|
|
187
174
|
html chart.run
|
|
188
175
|
end
|
|
189
176
|
|
|
@@ -216,4 +203,12 @@ class HtmlReportConfig
|
|
|
216
203
|
</section>
|
|
217
204
|
HTML
|
|
218
205
|
end
|
|
206
|
+
|
|
207
|
+
def discard_changes_before status_becomes: nil, &block
|
|
208
|
+
file_system.deprecated(
|
|
209
|
+
date: '2025-01-09',
|
|
210
|
+
message: 'discard_changes_before is now only supported at the project level'
|
|
211
|
+
)
|
|
212
|
+
file_config.project_config.discard_changes_before status_becomes: status_becomes, &block
|
|
213
|
+
end
|
|
219
214
|
end
|