rails_error_dashboard 0.8.3 → 0.9.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/README.md +35 -0
- data/app/controllers/rails_error_dashboard/application_controller.rb +156 -0
- data/app/controllers/rails_error_dashboard/errors_controller.rb +95 -73
- data/app/controllers/rails_error_dashboard/locales_controller.rb +87 -0
- data/app/helpers/rails_error_dashboard/application_helper.rb +20 -14
- data/app/helpers/rails_error_dashboard/backtrace_helper.rb +15 -6
- data/app/helpers/rails_error_dashboard/i18n_helper.rb +154 -0
- data/app/helpers/rails_error_dashboard/mailer_i18n_helper.rb +69 -0
- data/app/helpers/rails_error_dashboard/overview_helper.rb +18 -6
- data/app/helpers/rails_error_dashboard/user_agent_helper.rb +25 -11
- data/app/jobs/rails_error_dashboard/application_job.rb +5 -0
- data/app/jobs/rails_error_dashboard/baseline_alert_job.rb +18 -16
- data/app/jobs/rails_error_dashboard/concerns/localized_job.rb +83 -0
- data/app/jobs/rails_error_dashboard/discord_error_notification_job.rb +4 -2
- data/app/jobs/rails_error_dashboard/email_error_notification_job.rb +4 -2
- data/app/jobs/rails_error_dashboard/pagerduty_error_notification_job.rb +6 -2
- data/app/jobs/rails_error_dashboard/scheduled_digest_job.rb +8 -3
- data/app/jobs/rails_error_dashboard/slack_error_notification_job.rb +6 -4
- data/app/jobs/rails_error_dashboard/storm_notification_job.rb +26 -8
- data/app/jobs/rails_error_dashboard/webhook_error_notification_job.rb +4 -2
- data/app/mailers/rails_error_dashboard/application_mailer.rb +14 -0
- data/app/mailers/rails_error_dashboard/digest_mailer.rb +18 -2
- data/app/mailers/rails_error_dashboard/error_notification_mailer.rb +19 -2
- data/app/views/layouts/rails_error_dashboard.html.erb +255 -92
- data/app/views/rails_error_dashboard/digest_mailer/digest_summary.html.erb +23 -22
- data/app/views/rails_error_dashboard/digest_mailer/digest_summary.text.erb +30 -19
- data/app/views/rails_error_dashboard/error_notification_mailer/error_alert.html.erb +18 -16
- data/app/views/rails_error_dashboard/error_notification_mailer/error_alert.text.erb +21 -14
- data/app/views/rails_error_dashboard/errors/_ai_help_panel.html.erb +11 -7
- data/app/views/rails_error_dashboard/errors/_breadcrumbs_group.html.erb +45 -38
- data/app/views/rails_error_dashboard/errors/_co_occurring_errors.html.erb +17 -14
- data/app/views/rails_error_dashboard/errors/_discussion.html.erb +27 -9
- data/app/views/rails_error_dashboard/errors/_error_cascades.html.erb +25 -21
- data/app/views/rails_error_dashboard/errors/_error_info.html.erb +25 -22
- data/app/views/rails_error_dashboard/errors/_error_row.html.erb +24 -12
- data/app/views/rails_error_dashboard/errors/_instance_variables.html.erb +12 -11
- data/app/views/rails_error_dashboard/errors/_issue_section.html.erb +19 -13
- data/app/views/rails_error_dashboard/errors/_llm_summary.html.erb +14 -14
- data/app/views/rails_error_dashboard/errors/_local_variables.html.erb +8 -8
- data/app/views/rails_error_dashboard/errors/_modals.html.erb +60 -52
- data/app/views/rails_error_dashboard/errors/_pattern_insights.html.erb +59 -49
- data/app/views/rails_error_dashboard/errors/_request_context.html.erb +23 -20
- data/app/views/rails_error_dashboard/errors/_show_scripts.html.erb +14 -14
- data/app/views/rails_error_dashboard/errors/_sidebar_metadata.html.erb +118 -93
- data/app/views/rails_error_dashboard/errors/_similar_errors.html.erb +18 -12
- data/app/views/rails_error_dashboard/errors/_source_code.html.erb +20 -5
- data/app/views/rails_error_dashboard/errors/_stats.html.erb +5 -5
- data/app/views/rails_error_dashboard/errors/_timeline.html.erb +7 -7
- data/app/views/rails_error_dashboard/errors/_user_errors_table.html.erb +15 -12
- data/app/views/rails_error_dashboard/errors/actioncable_health_summary.html.erb +25 -25
- data/app/views/rails_error_dashboard/errors/activestorage_health_summary.html.erb +28 -28
- data/app/views/rails_error_dashboard/errors/analytics.html.erb +82 -82
- data/app/views/rails_error_dashboard/errors/cache_health_summary.html.erb +27 -27
- data/app/views/rails_error_dashboard/errors/correlation.html.erb +61 -57
- data/app/views/rails_error_dashboard/errors/database_health_summary.html.erb +64 -65
- data/app/views/rails_error_dashboard/errors/deprecations.html.erb +23 -23
- data/app/views/rails_error_dashboard/errors/diagnostic_dumps.html.erb +48 -36
- data/app/views/rails_error_dashboard/errors/index.html.erb +121 -70
- data/app/views/rails_error_dashboard/errors/job_health_summary.html.erb +30 -30
- data/app/views/rails_error_dashboard/errors/llm_health_summary.html.erb +38 -39
- data/app/views/rails_error_dashboard/errors/n_plus_one_summary.html.erb +28 -25
- data/app/views/rails_error_dashboard/errors/overview.html.erb +45 -39
- data/app/views/rails_error_dashboard/errors/platform_comparison.html.erb +45 -44
- data/app/views/rails_error_dashboard/errors/rack_attack_summary.html.erb +39 -28
- data/app/views/rails_error_dashboard/errors/releases.html.erb +46 -47
- data/app/views/rails_error_dashboard/errors/settings/_value_badge.html.erb +48 -44
- data/app/views/rails_error_dashboard/errors/settings.html.erb +122 -112
- data/app/views/rails_error_dashboard/errors/show.html.erb +44 -37
- data/app/views/rails_error_dashboard/errors/storms.html.erb +30 -24
- data/app/views/rails_error_dashboard/errors/swallowed_exceptions.html.erb +26 -26
- data/app/views/rails_error_dashboard/errors/user_impact.html.erb +31 -30
- data/config/locales/de.yml +2007 -0
- data/config/locales/en.yml +2719 -0
- data/config/locales/es.yml +2079 -0
- data/config/locales/fr.yml +2082 -0
- data/config/locales/it.yml +2060 -0
- data/config/locales/ja.yml +1802 -0
- data/config/locales/pl.yml +2108 -0
- data/config/locales/pt-BR.yml +2064 -0
- data/config/locales/ru.yml +2109 -0
- data/config/locales/uk.yml +2106 -0
- data/config/locales/zh-CN.yml +1791 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20260325000001_fix_swallowed_exceptions_index_for_mysql.rb +9 -3
- data/lib/rails_error_dashboard/commands/batch_delete_errors.rb +3 -1
- data/lib/rails_error_dashboard/commands/batch_mute_errors.rb +4 -2
- data/lib/rails_error_dashboard/commands/batch_resolve_errors.rb +4 -2
- data/lib/rails_error_dashboard/commands/batch_unmute_errors.rb +4 -2
- data/lib/rails_error_dashboard/commands/create_issue.rb +5 -3
- data/lib/rails_error_dashboard/commands/link_existing_issue.rb +4 -2
- data/lib/rails_error_dashboard/commands/log_error.rb +1 -1
- data/lib/rails_error_dashboard/configuration.rb +23 -0
- data/lib/rails_error_dashboard/current.rb +56 -0
- data/lib/rails_error_dashboard/i18n_store.rb +293 -0
- data/lib/rails_error_dashboard/private_backend.rb +213 -0
- data/lib/rails_error_dashboard/services/baseline_alert_payload_builder.rb +89 -22
- data/lib/rails_error_dashboard/services/digest_builder.rb +21 -7
- data/lib/rails_error_dashboard/services/discord_payload_builder.rb +27 -15
- data/lib/rails_error_dashboard/services/error_notification_dispatcher.rb +10 -5
- data/lib/rails_error_dashboard/services/localized_time_formatter.rb +117 -0
- data/lib/rails_error_dashboard/services/notification_helpers.rb +87 -4
- data/lib/rails_error_dashboard/services/pagerduty_payload_builder.rb +22 -5
- data/lib/rails_error_dashboard/services/slack_payload_builder.rb +48 -28
- data/lib/rails_error_dashboard/services/storm_protection/gate.rb +2 -1
- data/lib/rails_error_dashboard/services/webhook_payload_builder.rb +15 -1
- data/lib/rails_error_dashboard/translation.rb +39 -0
- data/lib/rails_error_dashboard/version.rb +1 -1
- data/lib/rails_error_dashboard.rb +4 -0
- data/lib/tasks/error_dashboard.rake +5 -1
- metadata +24 -4
|
@@ -1,40 +1,48 @@
|
|
|
1
|
-
<% content_for :page_title, "
|
|
1
|
+
<% content_for :page_title, red_t("red.errors.rack_attack_page.title") %>
|
|
2
2
|
|
|
3
3
|
<div>
|
|
4
4
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
5
5
|
<h1 style="font-size: 20px; font-weight: 700; margin: 0;">
|
|
6
6
|
<i class="bi bi-shield-exclamation me-2"></i>
|
|
7
|
-
|
|
7
|
+
<%= red_t("red.errors.rack_attack_page.title") %>
|
|
8
8
|
</h1>
|
|
9
9
|
|
|
10
10
|
<div class="btn-group" role="group">
|
|
11
11
|
<%= link_to rack_attack_summary_errors_path(days: 7), class: "btn btn-sm #{@days == 7 ? 'btn-primary' : 'btn-outline-primary'}" do %>
|
|
12
|
-
7
|
|
12
|
+
<%= red_t("red.common.days_filter.7") %>
|
|
13
13
|
<% end %>
|
|
14
14
|
<%= link_to rack_attack_summary_errors_path(days: 30), class: "btn btn-sm #{@days == 30 ? 'btn-primary' : 'btn-outline-primary'}" do %>
|
|
15
|
-
30
|
|
15
|
+
<%= red_t("red.common.days_filter.30") %>
|
|
16
16
|
<% end %>
|
|
17
17
|
<%= link_to rack_attack_summary_errors_path(days: 90), class: "btn btn-sm #{@days == 90 ? 'btn-primary' : 'btn-outline-primary'}" do %>
|
|
18
|
-
90
|
|
18
|
+
<%= red_t("red.common.days_filter.90") %>
|
|
19
19
|
<% end %>
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
23
|
<% if @unique_rules == 0 %>
|
|
24
24
|
<div class="red-empty-state">
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
<% if @rack_attack_missing %>
|
|
26
|
+
<i class="bi bi-exclamation-triangle display-1 text-warning mb-3"></i>
|
|
27
|
+
<div class="red-empty-state-title"><%= red_t("red.errors.rack_attack_page.missing_title") %></div>
|
|
28
|
+
<p class="text-muted">
|
|
29
|
+
<%= red_t("red.errors.rack_attack_page.missing_body_html", gem: content_tag(:code, "rack-attack")) %>
|
|
30
|
+
</p>
|
|
31
|
+
<% else %>
|
|
32
|
+
<i class="bi bi-shield-check display-1 text-success mb-3"></i>
|
|
33
|
+
<div class="red-empty-state-title"><%= red_t("red.errors.rack_attack_page.empty_title") %></div>
|
|
34
|
+
<p class="text-muted">
|
|
35
|
+
<%= red_t("red.errors.rack_attack_page.empty_body", days: @days) %>
|
|
36
|
+
</p>
|
|
37
|
+
<% end %>
|
|
30
38
|
<div class="card mx-auto" style="max-width: 500px;">
|
|
31
39
|
<div class="card-body text-start">
|
|
32
|
-
<h6
|
|
40
|
+
<h6><%= red_t("red.errors.rack_attack_page.how_title") %></h6>
|
|
33
41
|
<ul class="mb-0">
|
|
34
|
-
<li
|
|
35
|
-
<li
|
|
36
|
-
<li
|
|
37
|
-
<li
|
|
42
|
+
<li><%= red_t("red.errors.rack_attack_page.how_enabled_html", option: content_tag(:code, "enable_rack_attack_tracking = true")) %></li>
|
|
43
|
+
<li><%= red_t("red.errors.rack_attack_page.how_installed") %></li>
|
|
44
|
+
<li><%= red_t("red.errors.rack_attack_page.how_recorded") %></li>
|
|
45
|
+
<li><%= red_t("red.errors.rack_attack_page.how_buffered", seconds: RailsErrorDashboard.configuration.rack_attack_flush_interval) %></li>
|
|
38
46
|
</ul>
|
|
39
47
|
</div>
|
|
40
48
|
</div>
|
|
@@ -45,7 +53,7 @@
|
|
|
45
53
|
<div class="card text-center">
|
|
46
54
|
<div class="card-body">
|
|
47
55
|
<div class="display-6 text-warning"><%= @unique_rules %></div>
|
|
48
|
-
<small class="text-muted"
|
|
56
|
+
<small class="text-muted"><%= red_t("red.errors.rack_attack_page.unique_rules") %></small>
|
|
49
57
|
</div>
|
|
50
58
|
</div>
|
|
51
59
|
</div>
|
|
@@ -53,7 +61,7 @@
|
|
|
53
61
|
<div class="card text-center">
|
|
54
62
|
<div class="card-body">
|
|
55
63
|
<div class="display-6 text-danger"><%= @total_events %></div>
|
|
56
|
-
<small class="text-muted"
|
|
64
|
+
<small class="text-muted"><%= red_t("red.errors.rack_attack_page.total_events") %></small>
|
|
57
65
|
</div>
|
|
58
66
|
</div>
|
|
59
67
|
</div>
|
|
@@ -61,7 +69,7 @@
|
|
|
61
69
|
<div class="card text-center">
|
|
62
70
|
<div class="card-body">
|
|
63
71
|
<div class="display-6 text-info"><%= @unique_ips %></div>
|
|
64
|
-
<small class="text-muted"
|
|
72
|
+
<small class="text-muted"><%= red_t("red.errors.rack_attack_page.unique_ips") %></small>
|
|
65
73
|
</div>
|
|
66
74
|
</div>
|
|
67
75
|
</div>
|
|
@@ -71,7 +79,7 @@
|
|
|
71
79
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
72
80
|
<h5 class="mb-0">
|
|
73
81
|
<i class="bi bi-shield-exclamation text-warning me-2"></i>
|
|
74
|
-
|
|
82
|
+
<%= red_t("red.errors.rack_attack_page.all_title") %>
|
|
75
83
|
<span class="badge bg-warning text-dark"><%= @unique_rules %></span>
|
|
76
84
|
</h5>
|
|
77
85
|
<small class="text-muted"><%== @pagy.info_tag %></small>
|
|
@@ -81,12 +89,12 @@
|
|
|
81
89
|
<table class="table table-hover mb-0">
|
|
82
90
|
<thead class="table-light">
|
|
83
91
|
<tr>
|
|
84
|
-
<th
|
|
85
|
-
<th width="100"
|
|
86
|
-
<th width="80"
|
|
87
|
-
<th width="80"
|
|
88
|
-
<th
|
|
89
|
-
<th width="140"
|
|
92
|
+
<th><%= red_t("red.errors.rack_attack_page.column_rule") %></th>
|
|
93
|
+
<th width="100"><%= red_t("red.errors.rack_attack_page.column_type") %></th>
|
|
94
|
+
<th width="80"><%= red_t("red.errors.rack_attack_page.column_count") %></th>
|
|
95
|
+
<th width="80"><%= red_t("red.errors.rack_attack_page.column_ips") %></th>
|
|
96
|
+
<th><%= red_t("red.errors.rack_attack_page.column_top_path") %></th>
|
|
97
|
+
<th width="140"><%= red_t("red.errors.pages.column_last_seen") %></th>
|
|
90
98
|
</tr>
|
|
91
99
|
</thead>
|
|
92
100
|
<tbody>
|
|
@@ -99,7 +107,10 @@
|
|
|
99
107
|
when "throttle" then "warning"
|
|
100
108
|
else "secondary"
|
|
101
109
|
end %>
|
|
102
|
-
|
|
110
|
+
<%# The match type is a machine value the case above compares
|
|
111
|
+
by string equality, so the comparison keeps the English
|
|
112
|
+
literal and only the display goes through a key. %>
|
|
113
|
+
<span class="badge bg-<%= type_color %>"><%= red_t("red.errors.rack_attack_page.match_type.#{event[:match_type]}") %></span>
|
|
103
114
|
</td>
|
|
104
115
|
<td><strong><%= event[:count] %></strong></td>
|
|
105
116
|
<td><%= event[:unique_ips] %></td>
|
|
@@ -114,11 +125,11 @@
|
|
|
114
125
|
<div class="card-footer border-top d-flex justify-content-between align-items-center">
|
|
115
126
|
<div>
|
|
116
127
|
<small class="text-muted">
|
|
117
|
-
<i class="bi bi-lightbulb text-warning"></i>
|
|
128
|
+
<i class="bi bi-lightbulb text-warning"></i> <%= red_t("red.errors.rack_attack_page.footer_tip") %>
|
|
118
129
|
</small>
|
|
119
130
|
<small class="ms-3">
|
|
120
131
|
<a href="https://github.com/rack/rack-attack" target="_blank" rel="noopener" class="text-decoration-none">
|
|
121
|
-
<i class="bi bi-book"></i>
|
|
132
|
+
<i class="bi bi-book"></i> <%= red_t("red.errors.rack_attack_page.docs") %> <i class="bi bi-box-arrow-up-right" style="font-size: 0.7em;"></i>
|
|
122
133
|
</a>
|
|
123
134
|
</small>
|
|
124
135
|
</div>
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
<% content_for :page_title, "
|
|
1
|
+
<% content_for :page_title, red_t("red.analytics.releases.title") %>
|
|
2
2
|
|
|
3
3
|
<div>
|
|
4
4
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
5
5
|
<h1 style="font-size: 20px; font-weight: 700; margin: 0;">
|
|
6
6
|
<i class="bi bi-rocket-takeoff me-2"></i>
|
|
7
|
-
|
|
7
|
+
<%= red_t("red.analytics.releases.title") %>
|
|
8
8
|
</h1>
|
|
9
9
|
|
|
10
10
|
<div class="btn-group" role="group">
|
|
11
11
|
<%= link_to releases_errors_path(days: 7), class: "btn btn-sm #{@days == 7 ? 'btn-primary' : 'btn-outline-primary'}" do %>
|
|
12
|
-
7
|
|
12
|
+
<%= red_t("red.common.days_filter.7") %>
|
|
13
13
|
<% end %>
|
|
14
14
|
<%= link_to releases_errors_path(days: 30), class: "btn btn-sm #{@days == 30 ? 'btn-primary' : 'btn-outline-primary'}" do %>
|
|
15
|
-
30
|
|
15
|
+
<%= red_t("red.common.days_filter.30") %>
|
|
16
16
|
<% end %>
|
|
17
17
|
<%= link_to releases_errors_path(days: 90), class: "btn btn-sm #{@days == 90 ? 'btn-primary' : 'btn-outline-primary'}" do %>
|
|
18
|
-
90
|
|
18
|
+
<%= red_t("red.common.days_filter.90") %>
|
|
19
19
|
<% end %>
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
|
@@ -23,18 +23,20 @@
|
|
|
23
23
|
<% if @releases.empty? %>
|
|
24
24
|
<div class="red-empty-state">
|
|
25
25
|
<i class="bi bi-rocket-takeoff display-1 text-muted mb-3"></i>
|
|
26
|
-
<div class="red-empty-state-title"
|
|
26
|
+
<div class="red-empty-state-title"><%= red_t("red.analytics.releases.empty.title") %></div>
|
|
27
27
|
<p class="text-muted">
|
|
28
|
-
|
|
28
|
+
<%= red_t("red.analytics.releases.empty.message", days: @days) %>
|
|
29
29
|
</p>
|
|
30
30
|
<div class="card mx-auto" style="max-width: 500px;">
|
|
31
31
|
<div class="card-body text-start">
|
|
32
|
-
<h6
|
|
32
|
+
<h6><%= red_t("red.analytics.releases.empty.how_to_title") %></h6>
|
|
33
33
|
<ul class="mb-0">
|
|
34
|
-
<li
|
|
35
|
-
<li
|
|
36
|
-
<li
|
|
37
|
-
|
|
34
|
+
<li><%= red_t("red.analytics.releases.empty.step_config_html", option: content_tag(:code, "config.app_version")) %></li>
|
|
35
|
+
<li><%= red_t("red.analytics.releases.empty.step_env_html", env_var: content_tag(:code, "APP_VERSION")) %></li>
|
|
36
|
+
<li><%= red_t("red.analytics.releases.empty.step_git_sha_html",
|
|
37
|
+
git_sha: content_tag(:code, "GIT_SHA"), heroku: content_tag(:code, "HEROKU_SLUG_COMMIT"),
|
|
38
|
+
render: content_tag(:code, "RENDER_GIT_COMMIT")) %></li>
|
|
39
|
+
<li><%= red_t("red.analytics.releases.empty.step_captured") %></li>
|
|
38
40
|
</ul>
|
|
39
41
|
</div>
|
|
40
42
|
</div>
|
|
@@ -50,15 +52,15 @@
|
|
|
50
52
|
<div class="card text-center">
|
|
51
53
|
<div class="card-body">
|
|
52
54
|
<div class="display-6 text-primary"><%= @summary[:total_releases] %></div>
|
|
53
|
-
<small class="text-muted"
|
|
55
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.summary.releases") %></small>
|
|
54
56
|
</div>
|
|
55
57
|
</div>
|
|
56
58
|
</div>
|
|
57
59
|
<div class="col-md-3">
|
|
58
60
|
<div class="card text-center">
|
|
59
61
|
<div class="card-body">
|
|
60
|
-
<div class="display-6"><code><%= @summary[:current_version] || "
|
|
61
|
-
<small class="text-muted"
|
|
62
|
+
<div class="display-6"><code><%= @summary[:current_version] || red_t("red.common.not_available") %></code></div>
|
|
63
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.summary.current_release") %></small>
|
|
62
64
|
</div>
|
|
63
65
|
</div>
|
|
64
66
|
</div>
|
|
@@ -66,7 +68,7 @@
|
|
|
66
68
|
<div class="card text-center">
|
|
67
69
|
<div class="card-body">
|
|
68
70
|
<div class="display-6 text-warning"><%= @summary[:avg_errors_per_release] %></div>
|
|
69
|
-
<small class="text-muted"
|
|
71
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.summary.avg_errors") %></small>
|
|
70
72
|
</div>
|
|
71
73
|
</div>
|
|
72
74
|
</div>
|
|
@@ -77,7 +79,7 @@
|
|
|
77
79
|
problematic_count = @releases.count { |r| r[:problematic] }
|
|
78
80
|
%>
|
|
79
81
|
<div class="display-6 <%= problematic_count > 0 ? 'text-danger' : 'text-success' %>"><%= problematic_count %></div>
|
|
80
|
-
<small class="text-muted"
|
|
82
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.summary.problematic") %></small>
|
|
81
83
|
</div>
|
|
82
84
|
</div>
|
|
83
85
|
</div>
|
|
@@ -88,19 +90,19 @@
|
|
|
88
90
|
<div class="card mb-4 border-primary">
|
|
89
91
|
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
|
|
90
92
|
<h5 class="mb-0">
|
|
91
|
-
<i class="bi bi-broadcast"></i>
|
|
93
|
+
<i class="bi bi-broadcast"></i> <%= red_t("red.analytics.releases.current_card.title") %> <strong><%= current_release[:version] %></strong>
|
|
92
94
|
</h5>
|
|
93
|
-
<span class="badge bg-light text-primary"
|
|
95
|
+
<span class="badge bg-light text-primary"><%= red_t("red.analytics.releases.current_card.live_badge") %></span>
|
|
94
96
|
</div>
|
|
95
97
|
<div class="card-body">
|
|
96
98
|
<div class="row text-center">
|
|
97
99
|
<div class="col-md-2">
|
|
98
100
|
<div class="h4 mb-0"><%= current_release[:total_errors] %></div>
|
|
99
|
-
<small class="text-muted"
|
|
101
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.current_card.errors") %></small>
|
|
100
102
|
</div>
|
|
101
103
|
<div class="col-md-2">
|
|
102
104
|
<div class="h4 mb-0"><%= current_release[:unique_error_types] %></div>
|
|
103
|
-
<small class="text-muted"
|
|
105
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.current_card.error_types") %></small>
|
|
104
106
|
</div>
|
|
105
107
|
<div class="col-md-2">
|
|
106
108
|
<div class="h4 mb-0">
|
|
@@ -110,7 +112,7 @@
|
|
|
110
112
|
<span class="text-success">0</span>
|
|
111
113
|
<% end %>
|
|
112
114
|
</div>
|
|
113
|
-
<small class="text-muted"
|
|
115
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.current_card.new_errors") %></small>
|
|
114
116
|
</div>
|
|
115
117
|
<div class="col-md-2">
|
|
116
118
|
<%
|
|
@@ -123,18 +125,18 @@
|
|
|
123
125
|
%>
|
|
124
126
|
<div class="h4 mb-0">
|
|
125
127
|
<span class="badge bg-<%= stability_color %>">
|
|
126
|
-
<%= current_release[:stability].to_s
|
|
128
|
+
<%= red_t("red.analytics.stability.#{current_release[:stability]}", default: current_release[:stability].to_s) %>
|
|
127
129
|
</span>
|
|
128
130
|
</div>
|
|
129
|
-
<small class="text-muted"
|
|
131
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.current_card.stability") %></small>
|
|
130
132
|
</div>
|
|
131
133
|
<div class="col-md-2">
|
|
132
134
|
<% if current_release[:git_shas].any? %>
|
|
133
135
|
<div class="h4 mb-0"><%= git_commit_link(current_release[:git_shas].first) %></div>
|
|
134
136
|
<% else %>
|
|
135
|
-
<div class="h4 mb-0 text-muted"
|
|
137
|
+
<div class="h4 mb-0 text-muted"><%= red_t("red.common.not_available") %></div>
|
|
136
138
|
<% end %>
|
|
137
|
-
<small class="text-muted"
|
|
139
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.current_card.git_sha") %></small>
|
|
138
140
|
</div>
|
|
139
141
|
<div class="col-md-2">
|
|
140
142
|
<% if current_release[:delta_from_previous] %>
|
|
@@ -149,7 +151,7 @@
|
|
|
149
151
|
<% else %>
|
|
150
152
|
<div class="h4 mb-0 text-muted">—</div>
|
|
151
153
|
<% end %>
|
|
152
|
-
<small class="text-muted"
|
|
154
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.current_card.vs_previous") %></small>
|
|
153
155
|
</div>
|
|
154
156
|
</div>
|
|
155
157
|
</div>
|
|
@@ -161,7 +163,7 @@
|
|
|
161
163
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
162
164
|
<h5 class="mb-0">
|
|
163
165
|
<i class="bi bi-clock-history text-primary me-2"></i>
|
|
164
|
-
|
|
166
|
+
<%= red_t("red.analytics.releases.timeline.title") %>
|
|
165
167
|
<span class="badge bg-primary"><%= @summary[:total_releases] %></span>
|
|
166
168
|
</h5>
|
|
167
169
|
<small class="text-muted"><%== @pagy.info_tag %></small>
|
|
@@ -171,14 +173,14 @@
|
|
|
171
173
|
<table class="table table-hover mb-0">
|
|
172
174
|
<thead class="table-light">
|
|
173
175
|
<tr>
|
|
174
|
-
<th
|
|
175
|
-
<th
|
|
176
|
-
<th
|
|
177
|
-
<th width="100"
|
|
178
|
-
<th width="100"
|
|
179
|
-
<th width="120"
|
|
180
|
-
<th width="100"
|
|
181
|
-
<th width="120"
|
|
176
|
+
<th><%= red_t("red.analytics.releases.timeline.column_version") %></th>
|
|
177
|
+
<th><%= red_t("red.analytics.releases.timeline.column_git_sha") %></th>
|
|
178
|
+
<th><%= red_t("red.analytics.releases.timeline.column_time_range") %></th>
|
|
179
|
+
<th width="100"><%= red_t("red.analytics.releases.timeline.column_errors") %></th>
|
|
180
|
+
<th width="100"><%= red_t("red.analytics.releases.timeline.column_types") %></th>
|
|
181
|
+
<th width="120"><%= red_t("red.analytics.releases.timeline.column_new_errors") %></th>
|
|
182
|
+
<th width="100"><%= red_t("red.analytics.releases.timeline.column_stability") %></th>
|
|
183
|
+
<th width="120"><%= red_t("red.analytics.releases.timeline.column_vs_previous") %></th>
|
|
182
184
|
</tr>
|
|
183
185
|
</thead>
|
|
184
186
|
<tbody>
|
|
@@ -189,20 +191,20 @@
|
|
|
189
191
|
<strong><%= release[:version] %></strong>
|
|
190
192
|
<% end %>
|
|
191
193
|
<% if release[:current] %>
|
|
192
|
-
<span class="badge bg-primary ms-1"
|
|
194
|
+
<span class="badge bg-primary ms-1"><%= red_t("red.analytics.releases.timeline.current_badge") %></span>
|
|
193
195
|
<% end %>
|
|
194
196
|
<% if release[:problematic] %>
|
|
195
|
-
<span class="badge bg-danger ms-1"
|
|
197
|
+
<span class="badge bg-danger ms-1"><%= red_t("red.analytics.releases.timeline.problematic_badge") %></span>
|
|
196
198
|
<% end %>
|
|
197
199
|
</td>
|
|
198
200
|
<td>
|
|
199
201
|
<% if release[:git_shas].any? %>
|
|
200
202
|
<%= git_commit_link(release[:git_shas].first) %>
|
|
201
203
|
<% if release[:git_shas].size > 1 %>
|
|
202
|
-
<small class="text-muted"
|
|
204
|
+
<small class="text-muted"><%= red_t("red.analytics.releases.timeline.more_shas", count: release[:git_shas].size - 1) %></small>
|
|
203
205
|
<% end %>
|
|
204
206
|
<% else %>
|
|
205
|
-
<span class="text-muted"
|
|
207
|
+
<span class="text-muted"><%= red_t("red.common.not_available") %></span>
|
|
206
208
|
<% end %>
|
|
207
209
|
</td>
|
|
208
210
|
<td>
|
|
@@ -222,11 +224,11 @@
|
|
|
222
224
|
<td>
|
|
223
225
|
<% if release[:new_error_count] > 0 %>
|
|
224
226
|
<span class="badge bg-danger">
|
|
225
|
-
<i class="bi bi-exclamation-circle"></i> <%= release[:new_error_count] %>
|
|
227
|
+
<i class="bi bi-exclamation-circle"></i> <%= red_tp("red.analytics.releases.timeline.new_count", count: release[:new_error_count]) %>
|
|
226
228
|
</span>
|
|
227
229
|
<% else %>
|
|
228
230
|
<span class="badge bg-success">
|
|
229
|
-
<i class="bi bi-check-circle"></i> 0
|
|
231
|
+
<i class="bi bi-check-circle"></i> <%= red_tp("red.analytics.releases.timeline.new_count", count: 0) %>
|
|
230
232
|
</span>
|
|
231
233
|
<% end %>
|
|
232
234
|
</td>
|
|
@@ -241,7 +243,7 @@
|
|
|
241
243
|
%>
|
|
242
244
|
<span class="badge bg-<%= stability_color %>">
|
|
243
245
|
<i class="bi bi-circle-fill" style="font-size: 0.5em; vertical-align: middle;"></i>
|
|
244
|
-
<%= release[:stability].to_s
|
|
246
|
+
<%= red_t("red.analytics.stability.#{release[:stability]}", default: release[:stability].to_s) %>
|
|
245
247
|
</span>
|
|
246
248
|
</td>
|
|
247
249
|
<td>
|
|
@@ -272,10 +274,7 @@
|
|
|
272
274
|
<div class="card-footer border-top d-flex justify-content-between align-items-center">
|
|
273
275
|
<small class="text-muted">
|
|
274
276
|
<i class="bi bi-info-circle"></i>
|
|
275
|
-
|
|
276
|
-
<span class="badge bg-warning">Yellow</span> 1-2x avg,
|
|
277
|
-
<span class="badge bg-danger">Red</span> > 2x avg.
|
|
278
|
-
"New" errors are error types first seen in that release.
|
|
277
|
+
<%= red_t("red.analytics.releases.timeline.footer_html") %>
|
|
279
278
|
</small>
|
|
280
279
|
<div>
|
|
281
280
|
<%== @pagy.series_nav(:bootstrap) if @pagy.pages > 1 %>
|