good_job 4.4.1 → 4.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68dae79a3d669ccfd101719015e70aee8b54230c339012351ad677862732dc70
4
- data.tar.gz: d1242d0a898eff92aa4492d174de9cc73b0e610c5b1f56e358a304a864e39493
3
+ metadata.gz: f7a4560e3e97c78d26ea5045bbd6de6d378191a52873be4f213d886f80bdf29c
4
+ data.tar.gz: 98cc8a6958a69898966efe296339bfc22130c75d6700ad80934e60948f864861
5
5
  SHA512:
6
- metadata.gz: 4bac343036b068fa03559d168346c37e41b110e4e9e902af8c58209880afdf75e44301ea845aca208ba583245fd4f2aa486d80b0905492e830501851b5190bd8
7
- data.tar.gz: 576f825db2e84ae3ae3e19ccdf3e3a7becd2db81fb1960ebd26f18aa0779224ec4e79b0a976cd256cc0e19303e3b53d88b41f10be6a405ce284a731dd99654b4
6
+ metadata.gz: 1e1479d596427c82a6ed2b683aa0e8e171e20ab52b3591b49e757efd54b9ad5651c6a10643a42e3838c1042c2d17d96070d30888ceabff19b809185009c93e88
7
+ data.tar.gz: '0784732d866e3954803d23758a320d68adcd6ad9da30413419c514ffa5ea68a40dd3652eabd3847b24563814b2a37a48e1b55f2d8358a940daacbc6353fe8171'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [v4.4.2](https://github.com/bensheldon/good_job/tree/v4.4.2) (2024-10-18)
4
+
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v4.4.1...v4.4.2)
6
+
7
+ **Merged pull requests:**
8
+
9
+ - Bump rails from 7.1.4 to 7.1.4.1 [\#1524](https://github.com/bensheldon/good_job/pull/1524) ([Earlopain](https://github.com/Earlopain))
10
+ - Drop compatibility code for `ForkTracker` [\#1519](https://github.com/bensheldon/good_job/pull/1519) ([Earlopain](https://github.com/Earlopain))
11
+ - Add vertical legend to performance dashboard [\#1517](https://github.com/bensheldon/good_job/pull/1517) ([Wittiest](https://github.com/Wittiest))
12
+ - Bump the bundler-dependencies group across 1 directory with 10 updates [\#1515](https://github.com/bensheldon/good_job/pull/1515) ([dependabot[bot]](https://github.com/apps/dependabot))
13
+ - Manually bump tapioca / regenerate rbi [\#1514](https://github.com/bensheldon/good_job/pull/1514) ([Earlopain](https://github.com/Earlopain))
14
+ - Remove rack from the gemfile [\#1512](https://github.com/bensheldon/good_job/pull/1512) ([Earlopain](https://github.com/Earlopain))
15
+ - Add regression test for searchable numeric arguments [\#1510](https://github.com/bensheldon/good_job/pull/1510) ([bensheldon](https://github.com/bensheldon))
16
+ - Better parallelize CI jobs [\#1507](https://github.com/bensheldon/good_job/pull/1507) ([Earlopain](https://github.com/Earlopain))
17
+ - Bump webrick from 1.8.1 to 1.8.2 [\#1503](https://github.com/bensheldon/good_job/pull/1503) ([dependabot[bot]](https://github.com/apps/dependabot))
18
+
3
19
  ## [v4.4.1](https://github.com/bensheldon/good_job/tree/v4.4.1) (2024-10-10)
4
20
 
5
21
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v4.4.0...v4.4.1)
data/README.md CHANGED
@@ -1715,14 +1715,14 @@ Environment variables that may help with debugging:
1715
1715
  - `LOUD=1`: display all stdout/stderr output from all sources. This is helpful because GoodJob wraps some tests with `quiet { }` for cleaner test output, but it can hinder debugging.
1716
1716
  - `SHOW_BROWSER=1`: Run system tests headfully with Chrome/Chromedriver. Use `binding.irb` in the system tests to pause.
1717
1717
 
1718
- Appraisal can be used to run a test matrix of multiple versions of Rails:
1718
+ The gemfiles in `gemfiles/` can be used to run tests against different rails versions:
1719
1719
 
1720
1720
  ```bash
1721
- # Install Appraisal matrix of gemfiles
1722
- bin/appraisal
1721
+ # Install dependencies
1722
+ BUNDLE_GEMFILE=gemfiles/rails_6.1.gemfile bundle install
1723
1723
 
1724
- # Run tests against matrix
1725
- bin/appraisal bin/rspec
1724
+ # Run the tests
1725
+ BUNDLE_GEMFILE=gemfiles/rails_6.1.gemfile bin/rspec
1726
1726
  ```
1727
1727
 
1728
1728
  ### Release
@@ -56,6 +56,9 @@ module GoodJob
56
56
  display: true,
57
57
  text: I18n.t("good_job.performance.index.chart_title"),
58
58
  },
59
+ legend: {
60
+ vertical: true,
61
+ },
59
62
  },
60
63
  scales: {
61
64
  y: {
@@ -1,3 +1,5 @@
1
+ import htmlLegendPlugin from "html_legend_plugin";
2
+
1
3
  function renderCharts(animate) {
2
4
  const charts = document.querySelectorAll('.chart');
3
5
 
@@ -5,6 +7,16 @@ function renderCharts(animate) {
5
7
  const chartEl = charts[i];
6
8
  const chartData = JSON.parse(chartEl.dataset.json);
7
9
  chartData.options ||= {};
10
+
11
+ if (chartData.options.plugins?.legend?.vertical) {
12
+ chartData.plugins = [htmlLegendPlugin];
13
+ chartData.options.plugins = {
14
+ ...chartData.options.plugins,
15
+ legend: {
16
+ display: false,
17
+ }
18
+ }
19
+ }
8
20
  chartData.options.animation = animate;
9
21
  chartData.options.responsive = true;
10
22
  chartData.options.maintainAspectRatio = false;
@@ -0,0 +1,56 @@
1
+ const generateListItem = (item) => {
2
+ const li = document.createElement('li');
3
+ li.className = 'd-flex align-items-center text-nowrap mb-2';
4
+
5
+ const boxSpan = document.createElement('span');
6
+ boxSpan.className = 'legend-item-color-box';
7
+ boxSpan.style.background = item.fillStyle;
8
+ boxSpan.style.borderColor = item.strokeStyle;
9
+ boxSpan.style.borderWidth = item.lineWidth + 'px';
10
+
11
+ const textContainer = document.createElement('p');
12
+ textContainer.className = 'item-text m-0 small';
13
+ textContainer.style.color = item.fontColor;
14
+ textContainer.style.textDecoration = item.hidden ? 'line-through' : '';
15
+
16
+ const text = document.createTextNode(item.text);
17
+ textContainer.appendChild(text);
18
+
19
+ li.appendChild(boxSpan);
20
+ li.appendChild(textContainer);
21
+
22
+ return li;
23
+ }
24
+
25
+ const htmlLegendPlugin = {
26
+ id: 'htmlLegend',
27
+ afterUpdate(chart, _args, _options) {
28
+ const {type} = chart.config;
29
+ const ul = document.getElementById('chart-legend-ul');
30
+
31
+ // Remove old legend items
32
+ while (ul.firstChild) {
33
+ ul.firstChild.remove();
34
+ }
35
+
36
+ // Reuse the built-in legendItems generator
37
+ const items = chart.options.plugins.legend.labels.generateLabels(chart);
38
+
39
+ items.forEach(item => {
40
+ const li = generateListItem(item);
41
+ ul.appendChild(li);
42
+
43
+ li.onclick = () => {
44
+ if (type === 'pie' || type === 'doughnut') {
45
+ // Pie and doughnut charts only have a single dataset and visibility is per item
46
+ chart.toggleDataVisibility(item.index);
47
+ } else {
48
+ chart.setDatasetVisibility(item.datasetIndex, !chart.isDatasetVisible(item.datasetIndex));
49
+ }
50
+ chart.update();
51
+ };
52
+ });
53
+ }
54
+ };
55
+
56
+ export { htmlLegendPlugin as default };
@@ -24,6 +24,19 @@
24
24
  height: 200px;
25
25
  }
26
26
 
27
+ .legend-item-color-box {
28
+ display: inline-block;
29
+ flex-shrink: 0;
30
+ height: 20px;
31
+ width: 20px;
32
+ border-style: solid;
33
+ margin-right: 3px;
34
+ }
35
+
36
+ #chart-legend-container {
37
+ height: 200px;
38
+ }
39
+
27
40
  /* Break out of a container */
28
41
  .break-out {
29
42
  width:100vw;
@@ -1,5 +1,5 @@
1
1
  <%= render 'good_job/shared/filter', title: t("good_job.shared.navbar.jobs"), filter: @filter %>
2
- <%= render 'good_job/shared/chart', chart_data: GoodJob::ScheduledByQueueChart.new(@filter).data %>
2
+ <%= render 'good_job/shared/chart_container', chart_data: GoodJob::ScheduledByQueueChart.new(@filter).data %>
3
3
 
4
4
  <div data-live-poll-region="jobs-table">
5
5
  <%= render 'good_job/jobs/table', jobs: @filter.records, filter: @filter %>
@@ -2,7 +2,7 @@
2
2
  <h2 class="pt-3 pb-2"><%= t ".title" %></h2>
3
3
  </div>
4
4
 
5
- <%= render 'good_job/shared/chart', chart_data: GoodJob::PerformanceIndexChart.new.data %>
5
+ <%= render 'good_job/shared/chart_container', chart_data: GoodJob::PerformanceIndexChart.new.data %>
6
6
 
7
7
  <div class="my-3 card">
8
8
  <div class="list-group list-group-flush text-nowrap" role="table">
@@ -2,4 +2,4 @@
2
2
  <h2 class="pt-3 pb-2"><%= t ".title" %> - <%= @job_class %></h2>
3
3
  </div>
4
4
 
5
- <%= render 'good_job/shared/chart', chart_data: GoodJob::PerformanceShowChart.new(@job_class).data %>
5
+ <%= render 'good_job/shared/chart_container', chart_data: GoodJob::PerformanceShowChart.new(@job_class).data %>
@@ -1,5 +1,5 @@
1
- <div class="py-4" data-live-poll-region="chart">
2
- <div class="chart-wrapper container-fluid">
1
+ <div class="" data-live-poll-region="chart">
2
+ <div class="chart-wrapper">
3
3
  <canvas class="chart" data-json="<%= chart_data.to_json %>"></canvas>
4
4
  </div>
5
5
  </div>
@@ -0,0 +1,21 @@
1
+ <% vertical_legend = chart_data.dig(:options, :plugins, :legend, :vertical) %>
2
+
3
+ <div class="container-fluid">
4
+ <div class="row d-flex">
5
+ <% if vertical_legend %>
6
+ <div class="row d-flex">
7
+ <div class="col-md-10">
8
+ <%= render 'good_job/shared/chart', chart_data: chart_data %>
9
+ </div>
10
+ <div class="col-md-2 d-flex flex-column">
11
+ <div id="chart-legend-container" class="flex-fill overflow-auto">
12
+ <ul id="chart-legend-ul" class="list-unstyled p-0 mx-0 py-2">
13
+ </ul>
14
+ </div>
15
+ </div>
16
+ </div>
17
+ <% else %>
18
+ <%= render 'good_job/shared/chart', chart_data: chart_data %>
19
+ <% end %>
20
+ </div>
21
+ </div>
@@ -32,15 +32,7 @@ module GoodJob # :nodoc:
32
32
  @record = nil
33
33
  @refresh_task = nil
34
34
 
35
- # AS::ForkTracker is only present on Rails v6.1+.
36
- # Fall back to PID checking if ForkTracker is not available
37
- if defined?(ActiveSupport::ForkTracker)
38
- ActiveSupport::ForkTracker.after_fork { reset }
39
- @forktracker = true
40
- else
41
- @ruby_pid = ::Process.pid
42
- @forktracker = false
43
- end
35
+ ActiveSupport::ForkTracker.after_fork { reset }
44
36
 
45
37
  self.class.instances << self
46
38
  end
@@ -53,7 +45,6 @@ module GoodJob # :nodoc:
53
45
  synchronize do
54
46
  next if @locks.zero?
55
47
 
56
- reset_on_fork
57
48
  if @record
58
49
  @record.refresh_if_stale
59
50
  else
@@ -204,14 +195,6 @@ module GoodJob # :nodoc:
204
195
  synchronize { ns_reset }
205
196
  end
206
197
 
207
- def reset_on_fork
208
- return if Concurrent.on_jruby?
209
- return if @forktracker || ::Process.pid == @ruby_pid
210
-
211
- @ruby_pid = ::Process.pid
212
- ns_reset
213
- end
214
-
215
198
  def ns_reset
216
199
  @record_id = SecureRandom.uuid
217
200
  @record = nil
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GoodJob
4
4
  # GoodJob gem version.
5
- VERSION = '4.4.1'
5
+ VERSION = '4.4.2'
6
6
 
7
7
  # GoodJob version as Gem::Version object
8
8
  GEM_VERSION = Gem::Version.new(VERSION)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: good_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.1
4
+ version: 4.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Sheldon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-10 00:00:00.000000000 Z
11
+ date: 2024-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -269,6 +269,7 @@ files:
269
269
  - app/frontend/good_job/modules/charts.js
270
270
  - app/frontend/good_job/modules/checkbox_toggle.js
271
271
  - app/frontend/good_job/modules/document_ready.js
272
+ - app/frontend/good_job/modules/html_legend_plugin.js
272
273
  - app/frontend/good_job/modules/live_poll.js
273
274
  - app/frontend/good_job/modules/popovers.js
274
275
  - app/frontend/good_job/modules/theme_controller.js
@@ -315,6 +316,7 @@ files:
315
316
  - app/views/good_job/processes/index.html.erb
316
317
  - app/views/good_job/shared/_alert.erb
317
318
  - app/views/good_job/shared/_chart.erb
319
+ - app/views/good_job/shared/_chart_container.erb
318
320
  - app/views/good_job/shared/_filter.erb
319
321
  - app/views/good_job/shared/_footer.erb
320
322
  - app/views/good_job/shared/_navbar.erb