jirametrics 2.25 → 2.30
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/bin/jirametrics-mcp +5 -0
- data/lib/jirametrics/aging_work_bar_chart.rb +10 -8
- data/lib/jirametrics/aging_work_in_progress_chart.rb +43 -11
- data/lib/jirametrics/aging_work_table.rb +5 -2
- data/lib/jirametrics/board.rb +9 -1
- data/lib/jirametrics/cfd_data_builder.rb +5 -0
- data/lib/jirametrics/chart_base.rb +14 -2
- data/lib/jirametrics/cumulative_flow_diagram.rb +8 -0
- data/lib/jirametrics/cycletime_scatterplot.rb +4 -0
- data/lib/jirametrics/daily_view.rb +5 -4
- data/lib/jirametrics/data_quality_report.rb +3 -1
- data/lib/jirametrics/dependency_chart.rb +1 -1
- data/lib/jirametrics/downloader.rb +18 -7
- data/lib/jirametrics/downloader_for_cloud.rb +68 -22
- data/lib/jirametrics/downloader_for_data_center.rb +1 -1
- data/lib/jirametrics/examples/aggregated_project.rb +1 -1
- data/lib/jirametrics/examples/standard_project.rb +5 -2
- data/lib/jirametrics/exporter.rb +12 -1
- data/lib/jirametrics/file_config.rb +9 -11
- data/lib/jirametrics/file_system.rb +31 -2
- data/lib/jirametrics/flow_efficiency_scatterplot.rb +1 -1
- data/lib/jirametrics/github_gateway.rb +13 -4
- data/lib/jirametrics/groupable_issue_chart.rb +2 -0
- data/lib/jirametrics/grouping_rules.rb +5 -1
- data/lib/jirametrics/html/cumulative_flow_diagram.erb +7 -8
- data/lib/jirametrics/html/index.css +139 -88
- data/lib/jirametrics/html/index.erb +1 -0
- data/lib/jirametrics/html/index.js +1 -1
- data/lib/jirametrics/html/legacy_colors.css +174 -0
- data/lib/jirametrics/html/time_based_scatterplot.erb +8 -3
- data/lib/jirametrics/html/wip_by_column_chart.erb +250 -0
- data/lib/jirametrics/html_generator.rb +2 -1
- data/lib/jirametrics/html_report_config.rb +33 -27
- data/lib/jirametrics/issue.rb +99 -6
- data/lib/jirametrics/jira_gateway.rb +26 -7
- data/lib/jirametrics/mcp_server.rb +531 -0
- data/lib/jirametrics/project_config.rb +20 -1
- data/lib/jirametrics/pull_request_cycle_time_histogram.rb +2 -2
- data/lib/jirametrics/pull_request_cycle_time_scatterplot.rb +13 -6
- data/lib/jirametrics/sprint_burndown.rb +1 -1
- data/lib/jirametrics/stitcher.rb +5 -0
- data/lib/jirametrics/throughput_chart.rb +18 -2
- data/lib/jirametrics/time_based_scatterplot.rb +9 -2
- data/lib/jirametrics/wip_by_column_chart.rb +236 -0
- data/lib/jirametrics.rb +58 -0
- metadata +36 -2
|
@@ -65,22 +65,20 @@ class FileConfig
|
|
|
65
65
|
# most common usecase - the Team Dashboard from FocusedObjective.com. The rule for that one
|
|
66
66
|
# is that all empty values in the first column should be at the bottom.
|
|
67
67
|
def sort_output all_lines
|
|
68
|
-
all_lines.sort do |a, b|
|
|
69
|
-
result =
|
|
70
|
-
|
|
71
|
-
result = a[1..] <=> b[1..]
|
|
68
|
+
all_lines.each_with_index.sort do |(a, a_idx), (b, b_idx)|
|
|
69
|
+
result = if a[0] == b[0]
|
|
70
|
+
a[1..] <=> b[1..]
|
|
72
71
|
elsif a[0].nil?
|
|
73
|
-
|
|
72
|
+
1
|
|
74
73
|
elsif b[0].nil?
|
|
75
|
-
|
|
74
|
+
-1
|
|
76
75
|
else
|
|
77
|
-
|
|
76
|
+
a[0] <=> b[0]
|
|
78
77
|
end
|
|
79
78
|
|
|
80
|
-
#
|
|
81
|
-
result
|
|
82
|
-
|
|
83
|
-
end
|
|
79
|
+
# When objects aren't comparable, preserve original order for a stable sort.
|
|
80
|
+
result.nil? || result.zero? ? a_idx <=> b_idx : result
|
|
81
|
+
end.map(&:first)
|
|
84
82
|
end
|
|
85
83
|
|
|
86
84
|
def columns &block
|
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
require 'json'
|
|
4
4
|
|
|
5
5
|
class FileSystem
|
|
6
|
-
attr_accessor :logfile, :logfile_name
|
|
6
|
+
attr_accessor :logfile, :logfile_name, :log_only
|
|
7
7
|
|
|
8
8
|
def initialize
|
|
9
9
|
# In almost all cases, this will be immediately replaced in the Exporter
|
|
10
10
|
# but if we fail before we get that far, this will at least let a useful
|
|
11
11
|
# error show up on the console.
|
|
12
12
|
@logfile = $stdout
|
|
13
|
+
@log_only = false
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
# Effectively the same as File.read except it forces the encoding to UTF-8
|
|
@@ -59,7 +60,7 @@ class FileSystem
|
|
|
59
60
|
|
|
60
61
|
logfile.puts message
|
|
61
62
|
logfile.puts more if more
|
|
62
|
-
return
|
|
63
|
+
return if log_only || !also_write_to_stderr
|
|
63
64
|
|
|
64
65
|
# Obscure edge-case where we're trying to log something before logging is even
|
|
65
66
|
# set up. Quick escape here so that we don't dump the error twice.
|
|
@@ -68,6 +69,34 @@ class FileSystem
|
|
|
68
69
|
$stderr.puts message # rubocop:disable Style/StderrPuts
|
|
69
70
|
end
|
|
70
71
|
|
|
72
|
+
def log_start message
|
|
73
|
+
logfile.puts message
|
|
74
|
+
return if log_only || logfile == $stdout
|
|
75
|
+
|
|
76
|
+
$stderr.print message
|
|
77
|
+
$stderr.flush
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def start_progress
|
|
81
|
+
return if log_only
|
|
82
|
+
|
|
83
|
+
$stderr.print ' '
|
|
84
|
+
$stderr.flush
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def progress_dot
|
|
88
|
+
return if log_only
|
|
89
|
+
|
|
90
|
+
$stderr.print '.'
|
|
91
|
+
$stderr.flush
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def end_progress
|
|
95
|
+
return if log_only
|
|
96
|
+
|
|
97
|
+
$stderr.puts '' # rubocop:disable Style/StderrPuts
|
|
98
|
+
end
|
|
99
|
+
|
|
71
100
|
# In some Jira instances, a sizeable portion of the JSON is made up of empty fields. I've seen
|
|
72
101
|
# cases where this simple compression will drop the filesize by half.
|
|
73
102
|
def compress node
|
|
@@ -63,7 +63,7 @@ class FlowEfficiencyScatterplot < ChartBase
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
if data_sets.empty?
|
|
66
|
-
return "<h1 class='foldable'>#{@header_text}</h1>No data matched the selected criteria. Nothing to show
|
|
66
|
+
return "<h1 class='foldable'>#{@header_text}</h1><div>No data matched the selected criteria. Nothing to show.</div>"
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
wrap_and_render(binding, __FILE__)
|
|
@@ -64,9 +64,10 @@ class GithubGateway
|
|
|
64
64
|
raw_pr['body']
|
|
65
65
|
]
|
|
66
66
|
|
|
67
|
-
sources.compact
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
keys = sources.compact.flat_map { |s| s.scan(@issue_key_pattern) }.uniq
|
|
68
|
+
return keys unless keys.empty?
|
|
69
|
+
|
|
70
|
+
commit_messages_for(raw_pr['number']).flat_map { |msg| msg.scan(@issue_key_pattern) }.uniq
|
|
70
71
|
end
|
|
71
72
|
|
|
72
73
|
def extract_reviews raw_reviews
|
|
@@ -83,11 +84,19 @@ class GithubGateway
|
|
|
83
84
|
|
|
84
85
|
private
|
|
85
86
|
|
|
87
|
+
def commit_messages_for pr_number
|
|
88
|
+
args = ['pr', 'view', pr_number.to_s, '--json', 'commits', '--repo', @repo]
|
|
89
|
+
result = run_command(args)
|
|
90
|
+
(result['commits'] || []).flat_map do |commit|
|
|
91
|
+
[commit['messageHeadline'], commit['messageBody']].compact
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
86
95
|
def build_issue_key_pattern
|
|
87
96
|
return nil if @project_keys.empty?
|
|
88
97
|
|
|
89
98
|
keys_pattern = @project_keys.map { |k| Regexp.escape(k) }.join('|')
|
|
90
|
-
Regexp.new("\\b(?:#{keys_pattern})-\\d
|
|
99
|
+
Regexp.new("\\b(?:#{keys_pattern})-\\d+(?![A-Za-z0-9])")
|
|
91
100
|
end
|
|
92
101
|
|
|
93
102
|
def run_command args
|
|
@@ -17,6 +17,7 @@ module GroupableIssueChart
|
|
|
17
17
|
result = {}
|
|
18
18
|
ignored_issues = []
|
|
19
19
|
@issue_hints = {}
|
|
20
|
+
@issue_periods = {}
|
|
20
21
|
completed_issues.each do |issue|
|
|
21
22
|
rules = GroupingRules.new
|
|
22
23
|
@group_by_block.call(issue, rules)
|
|
@@ -26,6 +27,7 @@ module GroupableIssueChart
|
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
@issue_hints[issue] = rules.issue_hint
|
|
30
|
+
@issue_periods[issue] = rules.last_day_of_period
|
|
29
31
|
(result[rules] ||= []) << issue
|
|
30
32
|
end
|
|
31
33
|
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
class GroupingRules < Rules
|
|
4
4
|
attr_accessor :label, :issue_hint, :label_hint
|
|
5
|
-
attr_reader :color
|
|
5
|
+
attr_reader :color, :last_day_of_period
|
|
6
|
+
|
|
7
|
+
def last_day_of_period= value
|
|
8
|
+
@last_day_of_period = value.is_a?(String) ? Date.parse(value) : value
|
|
9
|
+
end
|
|
6
10
|
|
|
7
11
|
def eql? other
|
|
8
12
|
other.label == @label && other.color == @color
|
|
@@ -271,14 +271,6 @@ if (!Chart.Tooltip.positioners.legendItem) {
|
|
|
271
271
|
ctx.moveTo(xA, yB);
|
|
272
272
|
ctx.lineTo(xC, yA);
|
|
273
273
|
ctx.stroke();
|
|
274
|
-
} else {
|
|
275
|
-
// C outside range: dashed extension to right edge
|
|
276
|
-
ctx.setLineDash([4, 2]);
|
|
277
|
-
ctx.lineWidth = 1.5;
|
|
278
|
-
ctx.beginPath();
|
|
279
|
-
ctx.moveTo(xA, yA);
|
|
280
|
-
ctx.lineTo(ca.right, yA);
|
|
281
|
-
ctx.stroke();
|
|
282
274
|
}
|
|
283
275
|
|
|
284
276
|
ctx.restore();
|
|
@@ -310,6 +302,12 @@ if (!Chart.Tooltip.positioners.legendItem) {
|
|
|
310
302
|
id: 'cfdFlowMetrics',
|
|
311
303
|
|
|
312
304
|
afterInit(chart) {
|
|
305
|
+
// Guard against being applied to non-CFD charts (Chart.js may fire
|
|
306
|
+
// inline plugin hooks on other charts when plugins share an id with
|
|
307
|
+
// a cached entry).
|
|
308
|
+
const ds = chart.data.datasets;
|
|
309
|
+
if (!ds || !ds[0] || !ds[0].data || !ds[0].data.length) return;
|
|
310
|
+
|
|
313
311
|
const { arrivals, departures } = buildArrays(chart);
|
|
314
312
|
const dates = chart.data.datasets[0].data.map(d => new Date(d.x).getTime());
|
|
315
313
|
chart._flowMetrics = {
|
|
@@ -426,6 +424,7 @@ if (!Chart.Tooltip.positioners.legendItem) {
|
|
|
426
424
|
|
|
427
425
|
afterDraw(chart) {
|
|
428
426
|
const fm = chart._flowMetrics;
|
|
427
|
+
if (!fm) return;
|
|
429
428
|
drawTrendLines(chart, fm);
|
|
430
429
|
// Triangle is on the overlay canvas — no drawing needed here.
|
|
431
430
|
}
|
|
@@ -7,71 +7,78 @@
|
|
|
7
7
|
--cycletime-scatterplot-overall-trendline-color: gray;
|
|
8
8
|
|
|
9
9
|
--non-working-days-color: #F0F0F0;
|
|
10
|
-
--expedited-color:
|
|
11
|
-
--blocked-color: #
|
|
12
|
-
--stalled-color: orange
|
|
10
|
+
--expedited-color: #D55E00; /* Okabe-Ito vermilion */
|
|
11
|
+
--blocked-color: #D55E00; /* Okabe-Ito vermilion */
|
|
12
|
+
--stalled-color: #E69F00; /* Okabe-Ito orange */
|
|
13
13
|
--dead-color: black;
|
|
14
14
|
|
|
15
|
-
--type-story-color: #
|
|
16
|
-
--type-task-color: blue
|
|
17
|
-
--type-bug-color:
|
|
18
|
-
--type-spike-color: #
|
|
15
|
+
--type-story-color: #009E73; /* Okabe-Ito bluish green */
|
|
16
|
+
--type-task-color: #0072B2; /* Okabe-Ito blue */
|
|
17
|
+
--type-bug-color: #D55E00; /* Okabe-Ito vermilion */
|
|
18
|
+
--type-spike-color: #CC79A7; /* Okabe-Ito reddish purple */
|
|
19
19
|
|
|
20
20
|
--status-category-todo-color: gray;
|
|
21
|
-
--status-category-inprogress-color: #
|
|
22
|
-
--status-category-done-color: #
|
|
21
|
+
--status-category-inprogress-color: #0072B2; /* Okabe-Ito blue */
|
|
22
|
+
--status-category-done-color: #009E73; /* Okabe-Ito bluish green */
|
|
23
23
|
--status-category-unknown-color: black;
|
|
24
24
|
|
|
25
|
-
--aging-work-bar-chart-percentage-line-color:
|
|
25
|
+
--aging-work-bar-chart-percentage-line-color: #D55E00; /* Okabe-Ito vermilion */
|
|
26
26
|
--aging-work-bar-chart-separator-color: white;
|
|
27
27
|
|
|
28
28
|
--throughput_chart_total_line_color: gray;
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
--aging-work-in-progress-chart-shading-color: lightgray;
|
|
31
|
-
--aging-work-in-progress-chart-shading-50-color: #
|
|
32
|
-
--aging-work-in-progress-chart-shading-85-color: #
|
|
33
|
-
--aging-work-in-progress-chart-shading-98-color: #
|
|
34
|
-
--aging-work-in-progress-chart-shading-100-color: #
|
|
35
|
-
|
|
31
|
+
--aging-work-in-progress-chart-shading-50-color: #56B4E9; /* Okabe-Ito sky blue */
|
|
32
|
+
--aging-work-in-progress-chart-shading-85-color: #F0E442; /* Okabe-Ito yellow */
|
|
33
|
+
--aging-work-in-progress-chart-shading-98-color: #E69F00; /* Okabe-Ito orange */
|
|
34
|
+
--aging-work-in-progress-chart-shading-100-color: #D55E00; /* Okabe-Ito vermilion */
|
|
35
|
+
|
|
36
36
|
--aging-work-in-progress-by-age-trend-line-color: gray;
|
|
37
|
-
|
|
38
|
-
--aging-work-table-date-in-jeopardy: yellow
|
|
39
|
-
--aging-work-table-date-overdue:
|
|
37
|
+
|
|
38
|
+
--aging-work-table-date-in-jeopardy: #F0E442; /* Okabe-Ito yellow */
|
|
39
|
+
--aging-work-table-date-overdue: #D55E00; /* Okabe-Ito vermilion */
|
|
40
40
|
|
|
41
41
|
--hierarchy-table-inactive-item-text-color: gray;
|
|
42
42
|
|
|
43
|
-
--wip-chart-completed-color: #
|
|
44
|
-
--wip-chart-completed-but-not-started-color: #
|
|
45
|
-
--wip-chart-duration-less-than-day-color: #
|
|
46
|
-
--wip-chart-duration-week-or-less-color: #
|
|
47
|
-
--wip-chart-duration-two-weeks-or-less-color: #
|
|
48
|
-
--wip-chart-duration-four-weeks-or-less-color: #
|
|
49
|
-
--wip-chart-duration-more-than-four-weeks-color: #
|
|
50
|
-
--wip-chart-active-color: #
|
|
43
|
+
--wip-chart-completed-color: #009E73; /* Okabe-Ito bluish green */
|
|
44
|
+
--wip-chart-completed-but-not-started-color: #92D9C0; /* light bluish green */
|
|
45
|
+
--wip-chart-duration-less-than-day-color: #56B4E9; /* Okabe-Ito sky blue */
|
|
46
|
+
--wip-chart-duration-week-or-less-color: #F0E442; /* Okabe-Ito yellow */
|
|
47
|
+
--wip-chart-duration-two-weeks-or-less-color: #E69F00; /* Okabe-Ito orange */
|
|
48
|
+
--wip-chart-duration-four-weeks-or-less-color: #D55E00; /* Okabe-Ito vermilion */
|
|
49
|
+
--wip-chart-duration-more-than-four-weeks-color: #CC79A7; /* Okabe-Ito reddish purple */
|
|
50
|
+
--wip-chart-active-color: #0072B2; /* Okabe-Ito blue */
|
|
51
51
|
--wip-chart-border-color: gray;
|
|
52
52
|
|
|
53
|
-
--
|
|
54
|
-
--
|
|
55
|
-
--
|
|
56
|
-
--
|
|
53
|
+
--wip-by-column-chart-bar-fill-color: #0072B2; /* Okabe-Ito blue */
|
|
54
|
+
--wip-by-column-chart-bar-text-color: #ffffff;
|
|
55
|
+
--wip-by-column-chart-limit-line-color: #D55E00; /* Okabe-Ito vermilion */
|
|
56
|
+
--wip-by-column-chart-recommendation-color: #009E73; /* Okabe-Ito bluish green */
|
|
57
|
+
|
|
58
|
+
--estimate-accuracy-chart-completed-fill-color: #92D9C0; /* light bluish green */
|
|
59
|
+
--estimate-accuracy-chart-completed-border-color: #009E73; /* Okabe-Ito bluish green */
|
|
60
|
+
--estimate-accuracy-chart-active-fill-color: #F4C6AD; /* light vermilion */
|
|
61
|
+
--estimate-accuracy-chart-active-border-color: #D55E00; /* Okabe-Ito vermilion */
|
|
57
62
|
|
|
58
63
|
--expedited-chart-no-longer-expedited: gray;
|
|
59
|
-
--expedited-chart-dot-issue-started-color: orange
|
|
60
|
-
--expedited-chart-dot-issue-stopped-color: green
|
|
61
|
-
--expedited-chart-dot-expedite-started-color:
|
|
62
|
-
--expedited-chart-dot-expedite-stopped-color: green
|
|
64
|
+
--expedited-chart-dot-issue-started-color: #E69F00; /* Okabe-Ito orange */
|
|
65
|
+
--expedited-chart-dot-issue-stopped-color: #009E73; /* Okabe-Ito bluish green */
|
|
66
|
+
--expedited-chart-dot-expedite-started-color: #D55E00; /* Okabe-Ito vermilion */
|
|
67
|
+
--expedited-chart-dot-expedite-stopped-color: #009E73; /* Okabe-Ito bluish green */
|
|
63
68
|
|
|
64
|
-
--sprint-burndown-sprint-color-1: blue
|
|
65
|
-
--sprint-burndown-sprint-color-2: orange
|
|
66
|
-
--sprint-burndown-sprint-color-3: green
|
|
67
|
-
--sprint-burndown-sprint-color-4:
|
|
68
|
-
--sprint-burndown-sprint-color-5:
|
|
69
|
+
--sprint-burndown-sprint-color-1: #0072B2; /* Okabe-Ito blue */
|
|
70
|
+
--sprint-burndown-sprint-color-2: #E69F00; /* Okabe-Ito orange */
|
|
71
|
+
--sprint-burndown-sprint-color-3: #009E73; /* Okabe-Ito bluish green */
|
|
72
|
+
--sprint-burndown-sprint-color-4: #D55E00; /* Okabe-Ito vermilion */
|
|
73
|
+
--sprint-burndown-sprint-color-5: #CC79A7; /* Okabe-Ito reddish purple */
|
|
74
|
+
--sprint-burndown-sprint-color-6: #56B4E9; /* Okabe-Ito sky blue */
|
|
75
|
+
--sprint-burndown-sprint-color-7: #F0E442; /* Okabe-Ito yellow */
|
|
69
76
|
|
|
70
|
-
--sprint-color:
|
|
77
|
+
--sprint-color: #56B4E9; /* Okabe-Ito sky blue */
|
|
71
78
|
|
|
72
79
|
--daily-view-selected-issue-background: lightgray;
|
|
73
|
-
--daily-view-issue-border: green
|
|
74
|
-
--daily-view-selected-issue-border:
|
|
80
|
+
--daily-view-issue-border: #009E73; /* Okabe-Ito bluish green */
|
|
81
|
+
--daily-view-selected-issue-border: #D55E00; /* Okabe-Ito vermilion */
|
|
75
82
|
|
|
76
83
|
/* The first five are the standard priorities that Jira creates by default. */
|
|
77
84
|
--priority-color-highest: #dc2626; /* red-600 - urgent red */
|
|
@@ -221,25 +228,39 @@ div.child_issue {
|
|
|
221
228
|
html[data-theme="dark"] {
|
|
222
229
|
--warning-banner: #9F2B00;
|
|
223
230
|
--non-working-days-color: #2f2f2f;
|
|
224
|
-
--type-story-color: #
|
|
225
|
-
--type-task-color: #
|
|
226
|
-
--type-bug-color: #
|
|
231
|
+
--type-story-color: #2DCB9A; /* lighter bluish green for dark bg */
|
|
232
|
+
--type-task-color: #56B4E9; /* sky blue for dark bg */
|
|
233
|
+
--type-bug-color: #E69F00; /* orange instead of vermilion for dark bg */
|
|
227
234
|
--body-background: #343434;
|
|
228
235
|
--default-text-color: #aaa;
|
|
229
236
|
--grid-line-color: #424242;
|
|
230
|
-
--expedited-color: #
|
|
231
|
-
--blocked-color: #
|
|
232
|
-
--stalled-color: #
|
|
233
|
-
--wip-chart-active-color: #
|
|
234
|
-
--status-category-inprogress-color: #
|
|
237
|
+
--expedited-color: #E69F00; /* Okabe-Ito orange for dark bg */
|
|
238
|
+
--blocked-color: #E69F00; /* Okabe-Ito orange for dark bg */
|
|
239
|
+
--stalled-color: #F0E442; /* Okabe-Ito yellow — distinct from blocked */
|
|
240
|
+
--wip-chart-active-color: #56B4E9; /* sky blue for dark bg */
|
|
241
|
+
--status-category-inprogress-color: #56B4E9; /* sky blue for dark bg */
|
|
242
|
+
--status-category-done-color: #2DCB9A; /* lighter bluish green for dark bg */
|
|
235
243
|
--hierarchy-table-inactive-item-text-color: #939393;
|
|
236
|
-
--wip-chart-
|
|
237
|
-
--wip-
|
|
238
|
-
--wip-
|
|
239
|
-
--wip-
|
|
240
|
-
--wip-chart-
|
|
241
|
-
--wip-chart-duration-more-than-four-weeks-color: #
|
|
244
|
+
--wip-by-column-chart-bar-fill-color: #56B4E9; /* Okabe-Ito sky blue */
|
|
245
|
+
--wip-by-column-chart-bar-text-color: #000000;
|
|
246
|
+
--wip-by-column-chart-limit-line-color: #E69F00; /* Okabe-Ito orange */
|
|
247
|
+
--wip-by-column-chart-recommendation-color: #2DCB9A; /* lighter bluish green for dark bg */
|
|
248
|
+
--wip-chart-completed-color: #2DCB9A; /* lighter bluish green */
|
|
249
|
+
--wip-chart-duration-more-than-four-weeks-color: #DE9AC4; /* lighter reddish purple */
|
|
250
|
+
--estimate-accuracy-chart-completed-border-color: #2DCB9A;
|
|
251
|
+
--estimate-accuracy-chart-active-border-color: #E69F00;
|
|
252
|
+
--expedited-chart-dot-issue-stopped-color: #2DCB9A;
|
|
253
|
+
--expedited-chart-dot-expedite-started-color: #E69F00;
|
|
254
|
+
--expedited-chart-dot-expedite-stopped-color: #2DCB9A;
|
|
255
|
+
--sprint-burndown-sprint-color-1: #56B4E9; /* sky blue */
|
|
256
|
+
--sprint-burndown-sprint-color-3: #2DCB9A; /* lighter bluish green */
|
|
257
|
+
--sprint-burndown-sprint-color-4: #CC79A7; /* reddish purple (vermilion → orange conflicts with color-2) */
|
|
258
|
+
--sprint-burndown-sprint-color-5: #F0E442; /* yellow */
|
|
259
|
+
--sprint-burndown-sprint-color-6: #D55E00; /* vermilion (sky blue conflicts with color-1) */
|
|
260
|
+
--sprint-burndown-sprint-color-7: #92D9C0; /* light teal (yellow conflicts with color-5) */
|
|
242
261
|
--daily-view-selected-issue-background: #474747;
|
|
262
|
+
--daily-view-issue-border: #2DCB9A;
|
|
263
|
+
--daily-view-selected-issue-border: #E69F00;
|
|
243
264
|
--priority-color-highest: #ef4444;
|
|
244
265
|
--priority-color-high: #f97316;
|
|
245
266
|
--priority-color-low: #06b6d4;
|
|
@@ -262,25 +283,33 @@ html[data-theme="dark"] {
|
|
|
262
283
|
html[data-theme="light"] {
|
|
263
284
|
--warning-banner: yellow;
|
|
264
285
|
--non-working-days-color: #F0F0F0;
|
|
265
|
-
--type-story-color: #
|
|
266
|
-
--type-task-color: blue
|
|
267
|
-
--type-bug-color:
|
|
286
|
+
--type-story-color: #009E73; /* Okabe-Ito bluish green */
|
|
287
|
+
--type-task-color: #0072B2; /* Okabe-Ito blue */
|
|
288
|
+
--type-bug-color: #D55E00; /* Okabe-Ito vermilion */
|
|
268
289
|
--body-background: white;
|
|
269
290
|
--default-text-color: black;
|
|
270
291
|
--grid-line-color: lightgray;
|
|
271
|
-
--expedited-color:
|
|
272
|
-
--blocked-color: #
|
|
273
|
-
--stalled-color: orange
|
|
274
|
-
--wip-chart-active-color: #
|
|
275
|
-
--status-category-inprogress-color: #
|
|
292
|
+
--expedited-color: #D55E00; /* Okabe-Ito vermilion */
|
|
293
|
+
--blocked-color: #D55E00; /* Okabe-Ito vermilion */
|
|
294
|
+
--stalled-color: #E69F00; /* Okabe-Ito orange */
|
|
295
|
+
--wip-chart-active-color: #0072B2; /* Okabe-Ito blue */
|
|
296
|
+
--status-category-inprogress-color: #0072B2; /* Okabe-Ito blue */
|
|
297
|
+
--status-category-done-color: #009E73; /* Okabe-Ito bluish green */
|
|
276
298
|
--hierarchy-table-inactive-item-text-color: gray;
|
|
277
|
-
--wip-chart-
|
|
278
|
-
--wip-
|
|
279
|
-
--wip-
|
|
280
|
-
--wip-
|
|
281
|
-
--wip-chart-
|
|
282
|
-
--wip-chart-
|
|
299
|
+
--wip-by-column-chart-bar-fill-color: #0072B2;
|
|
300
|
+
--wip-by-column-chart-bar-text-color: #ffffff;
|
|
301
|
+
--wip-by-column-chart-limit-line-color: #D55E00;
|
|
302
|
+
--wip-by-column-chart-recommendation-color: #009E73;
|
|
303
|
+
--wip-chart-completed-color: #009E73; /* Okabe-Ito bluish green */
|
|
304
|
+
--wip-chart-completed-but-not-started-color: #92D9C0;
|
|
305
|
+
--wip-chart-duration-less-than-day-color: #56B4E9;
|
|
306
|
+
--wip-chart-duration-week-or-less-color: #F0E442;
|
|
307
|
+
--wip-chart-duration-two-weeks-or-less-color: #E69F00;
|
|
308
|
+
--wip-chart-duration-four-weeks-or-less-color: #D55E00;
|
|
309
|
+
--wip-chart-duration-more-than-four-weeks-color: #CC79A7;
|
|
283
310
|
--daily-view-selected-issue-background: lightgray;
|
|
311
|
+
--daily-view-issue-border: #009E73;
|
|
312
|
+
--daily-view-selected-issue-border: #D55E00;
|
|
284
313
|
--priority-color-highest: #dc2626;
|
|
285
314
|
--priority-color-high: #ea580c;
|
|
286
315
|
--priority-color-low: #0891b2;
|
|
@@ -336,41 +365,63 @@ html[data-theme="light"] {
|
|
|
336
365
|
--warning-banner: #9F2B00;
|
|
337
366
|
|
|
338
367
|
--non-working-days-color: #2f2f2f;
|
|
339
|
-
--type-story-color: #
|
|
340
|
-
--type-task-color: #
|
|
341
|
-
--type-bug-color: #
|
|
368
|
+
--type-story-color: #2DCB9A; /* lighter bluish green for dark bg */
|
|
369
|
+
--type-task-color: #56B4E9; /* sky blue for dark bg */
|
|
370
|
+
--type-bug-color: #E69F00; /* orange instead of vermilion for dark bg */
|
|
342
371
|
|
|
343
372
|
--body-background: #343434;
|
|
344
373
|
--default-text-color: #aaa;
|
|
345
374
|
--grid-line-color: #424242;
|
|
346
375
|
|
|
347
|
-
--expedited-color: #
|
|
348
|
-
--blocked-color: #
|
|
349
|
-
--stalled-color: #
|
|
376
|
+
--expedited-color: #E69F00; /* Okabe-Ito orange for dark bg */
|
|
377
|
+
--blocked-color: #E69F00; /* Okabe-Ito orange for dark bg */
|
|
378
|
+
--stalled-color: #F0E442; /* Okabe-Ito yellow — distinct from blocked */
|
|
350
379
|
--dead-color: black;
|
|
351
|
-
--wip-chart-active-color: #
|
|
380
|
+
--wip-chart-active-color: #56B4E9; /* sky blue for dark bg */
|
|
381
|
+
|
|
382
|
+
--status-category-inprogress-color: #56B4E9; /* sky blue for dark bg */
|
|
383
|
+
--status-category-done-color: #2DCB9A; /* lighter bluish green for dark bg */
|
|
352
384
|
|
|
353
|
-
--
|
|
385
|
+
--wip-by-column-chart-bar-fill-color: #56B4E9;
|
|
386
|
+
--wip-by-column-chart-bar-text-color: #000000;
|
|
387
|
+
--wip-by-column-chart-limit-line-color: #E69F00;
|
|
388
|
+
--wip-by-column-chart-recommendation-color: #2DCB9A;
|
|
354
389
|
|
|
355
390
|
--cycletime-scatterplot-overall-trendline-color: gray;
|
|
356
391
|
|
|
357
392
|
--hierarchy-table-inactive-item-text-color: #939393;
|
|
358
393
|
|
|
359
|
-
--wip-chart-completed-color: #
|
|
360
|
-
--wip-chart-completed-but-not-started-color: #
|
|
361
|
-
--wip-chart-duration-less-than-day-color: #
|
|
362
|
-
--wip-chart-duration-week-or-less-color: #
|
|
363
|
-
--wip-chart-duration-two-weeks-or-less-color: #
|
|
364
|
-
--wip-chart-duration-four-weeks-or-less-color: #
|
|
365
|
-
--wip-chart-duration-more-than-four-weeks-color: #
|
|
394
|
+
--wip-chart-completed-color: #2DCB9A; /* lighter bluish green */
|
|
395
|
+
--wip-chart-completed-but-not-started-color: #92D9C0;
|
|
396
|
+
--wip-chart-duration-less-than-day-color: #56B4E9;
|
|
397
|
+
--wip-chart-duration-week-or-less-color: #F0E442;
|
|
398
|
+
--wip-chart-duration-two-weeks-or-less-color: #E69F00;
|
|
399
|
+
--wip-chart-duration-four-weeks-or-less-color: #D55E00;
|
|
400
|
+
--wip-chart-duration-more-than-four-weeks-color: #DE9AC4; /* lighter reddish purple */
|
|
401
|
+
|
|
402
|
+
--estimate-accuracy-chart-completed-border-color: #2DCB9A;
|
|
403
|
+
--estimate-accuracy-chart-active-border-color: #E69F00;
|
|
404
|
+
|
|
405
|
+
--expedited-chart-dot-issue-stopped-color: #2DCB9A;
|
|
406
|
+
--expedited-chart-dot-expedite-started-color: #E69F00;
|
|
407
|
+
--expedited-chart-dot-expedite-stopped-color: #2DCB9A;
|
|
408
|
+
|
|
409
|
+
--sprint-burndown-sprint-color-1: #56B4E9; /* sky blue */
|
|
410
|
+
--sprint-burndown-sprint-color-3: #2DCB9A; /* lighter bluish green */
|
|
411
|
+
--sprint-burndown-sprint-color-4: #CC79A7; /* reddish purple (vermilion → orange conflicts with color-2) */
|
|
412
|
+
--sprint-burndown-sprint-color-5: #F0E442; /* yellow */
|
|
413
|
+
--sprint-burndown-sprint-color-6: #D55E00; /* vermilion (sky blue conflicts with color-1) */
|
|
414
|
+
--sprint-burndown-sprint-color-7: #92D9C0; /* light teal (yellow conflicts with color-5) */
|
|
366
415
|
|
|
367
416
|
--daily-view-selected-issue-background: #474747;
|
|
417
|
+
--daily-view-issue-border: #2DCB9A;
|
|
418
|
+
--daily-view-selected-issue-border: #E69F00;
|
|
368
419
|
|
|
369
420
|
--priority-color-highest: #ef4444; /* red-500 - bright urgent red */
|
|
370
421
|
--priority-color-high: #f97316; /* orange-500 - bright orange */
|
|
371
422
|
--priority-color-medium: #9ca3af; /* gray-400 - neutral light gray */
|
|
372
423
|
--priority-color-low: #06b6d4; /* cyan-500 - bright calm blue */
|
|
373
|
-
--priority-color-lowest: #94a3b8; /* slate-400 - muted light slate */
|
|
424
|
+
--priority-color-lowest: #94a3b8; /* slate-400 - muted light slate */
|
|
374
425
|
}
|
|
375
426
|
|
|
376
427
|
a[href] {
|
|
@@ -406,4 +457,4 @@ html[data-theme="light"] {
|
|
|
406
457
|
}
|
|
407
458
|
}
|
|
408
459
|
|
|
409
|
-
}
|
|
460
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<html>
|
|
2
2
|
<head>
|
|
3
3
|
<meta charset="UTF-8">
|
|
4
|
+
<title><%= project_name.empty? ? 'JiraMetrics' : "JiraMetrics - #{project_name}" %></title>
|
|
4
5
|
<link rel="icon" type="image/png" href="https://github.com/mikebowler/jirametrics/blob/main/favicon.png?raw=true" />
|
|
5
6
|
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.js"></script>
|
|
6
7
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
@@ -35,7 +35,7 @@ function makeFoldable() {
|
|
|
35
35
|
const toggleButton = document.createElement(element.tagName); //'button');
|
|
36
36
|
toggleButton.id = toggleId;
|
|
37
37
|
toggleButton.className = 'foldable-toggle-btn';
|
|
38
|
-
toggleButton.innerHTML = '▼ ' + element.
|
|
38
|
+
toggleButton.innerHTML = '▼ ' + element.innerHTML;
|
|
39
39
|
|
|
40
40
|
// Create a content container
|
|
41
41
|
const contentContainer = document.createElement('div');
|