good_job 2.14.1 → 2.14.2
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/CHANGELOG.md +18 -0
- data/engine/app/assets/good_job/modules/application.js +4 -2
- data/engine/app/assets/good_job/modules/live_poll.js +81 -0
- data/engine/app/controllers/good_job/cron_entries_controller.rb +2 -2
- data/engine/app/controllers/good_job/jobs_controller.rb +2 -2
- data/engine/app/filters/good_job/base_filter.rb +4 -2
- data/engine/app/filters/good_job/jobs_filter.rb +2 -1
- data/engine/app/views/good_job/cron_entries/show.html.erb +1 -1
- data/engine/app/views/good_job/executions/_table.erb +1 -1
- data/engine/app/views/good_job/jobs/_table.erb +12 -3
- data/engine/app/views/good_job/jobs/index.html.erb +14 -12
- data/engine/app/views/good_job/processes/index.html.erb +1 -1
- data/engine/app/views/good_job/shared/_chart.erb +1 -1
- data/engine/app/views/good_job/shared/_filter.erb +1 -1
- data/engine/app/views/good_job/shared/_footer.erb +1 -1
- data/engine/app/views/good_job/shared/_navbar.erb +5 -5
- data/engine/config/routes.rb +1 -1
- data/lib/good_job/configuration.rb +1 -1
- data/lib/good_job/version.rb +1 -1
- metadata +3 -3
- data/engine/app/assets/good_job/modules/poller.js +0 -93
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 723ecfed33656e11fcabed4f807c7b9735e474cf15701d97faa0d95c84dd4280
|
4
|
+
data.tar.gz: 210f4f8c8d420d46630292212c015d245c2035e8e79dc1b3148fcb40e1b8dbd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20f4b5844debd83589f2dc4f9cebe7be963f9dd7ec6749227db7fad00aca4366cdb87003776194695db84f2bc23739b65f866460d92622dbad8923ff690b9799
|
7
|
+
data.tar.gz: 3528895af9ce6f1d4d2e33dab0b6a2fa60cb255d3211a0cfc5b0e97d0f2444e7270c696872c47562dd18d822a95a550345068073a50f80d7ebdd0c9eac782bf8
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v2.14.2](https://github.com/bensheldon/good_job/tree/v2.14.2) (2022-05-01)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.14.1...v2.14.2)
|
6
|
+
|
7
|
+
**Fixed bugs:**
|
8
|
+
|
9
|
+
- Reintroduce fixed "Apply to all" mass action [\#586](https://github.com/bensheldon/good_job/pull/586) ([bensheldon](https://github.com/bensheldon))
|
10
|
+
|
11
|
+
**Closed issues:**
|
12
|
+
|
13
|
+
- how to get the number of tasks in the queue and the size of the queue? [\#564](https://github.com/bensheldon/good_job/issues/564)
|
14
|
+
- GoodJob tells me to upgrade but migrations fail [\#544](https://github.com/bensheldon/good_job/issues/544)
|
15
|
+
|
16
|
+
**Merged pull requests:**
|
17
|
+
|
18
|
+
- Update development dependencies [\#584](https://github.com/bensheldon/good_job/pull/584) ([bensheldon](https://github.com/bensheldon))
|
19
|
+
- Refactor Dashboard Live Poll javascript [\#582](https://github.com/bensheldon/good_job/pull/582) ([bensheldon](https://github.com/bensheldon))
|
20
|
+
|
3
21
|
## [v2.14.1](https://github.com/bensheldon/good_job/tree/v2.14.1) (2022-04-26)
|
4
22
|
|
5
23
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.14.0...v2.14.1)
|
@@ -4,11 +4,13 @@ import renderCharts from "charts";
|
|
4
4
|
import checkboxToggle from "checkbox_toggle";
|
5
5
|
import documentReady from "document_ready";
|
6
6
|
import showToasts from "toasts";
|
7
|
-
import
|
7
|
+
import LivePoll from "live_poll";
|
8
8
|
|
9
9
|
documentReady(function() {
|
10
10
|
renderCharts();
|
11
11
|
showToasts();
|
12
12
|
checkboxToggle();
|
13
|
-
|
13
|
+
|
14
|
+
const livePoll = new LivePoll
|
15
|
+
livePoll.start();
|
14
16
|
});
|
@@ -0,0 +1,81 @@
|
|
1
|
+
/*jshint esversion: 6, strict: false */
|
2
|
+
import renderCharts from "charts";
|
3
|
+
|
4
|
+
const MINIMUM_POLL_INTERVAL = 1;
|
5
|
+
const STORAGE_KEY = "live_poll";
|
6
|
+
|
7
|
+
function getStorage(key) {
|
8
|
+
const value = localStorage.getItem('good_job-' + key);
|
9
|
+
|
10
|
+
if (value === 'true') {
|
11
|
+
return true;
|
12
|
+
} else if (value === 'false') {
|
13
|
+
return false;
|
14
|
+
} else {
|
15
|
+
return value;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
function setStorage(key, value) {
|
20
|
+
localStorage.setItem('good_job-' + key, value);
|
21
|
+
}
|
22
|
+
|
23
|
+
function removeStorage(key) {
|
24
|
+
localStorage.removeItem('good_job-' + key);
|
25
|
+
}
|
26
|
+
|
27
|
+
export default class LivePoll {
|
28
|
+
start() {
|
29
|
+
const checkbox = document.querySelector('input[name="live_poll"]');
|
30
|
+
|
31
|
+
if (!checkbox.checked && getStorage(STORAGE_KEY)) {
|
32
|
+
checkbox.checked = true;
|
33
|
+
checkbox.value = getStorage(STORAGE_KEY)
|
34
|
+
}
|
35
|
+
|
36
|
+
checkbox.addEventListener('change', () => {
|
37
|
+
this.togglePolling();
|
38
|
+
});
|
39
|
+
|
40
|
+
this.togglePolling();
|
41
|
+
}
|
42
|
+
|
43
|
+
togglePolling = () => {
|
44
|
+
const checkbox = document.querySelector('input[name="live_poll"]');
|
45
|
+
const enabled = checkbox.checked;
|
46
|
+
const pollIntervalMilliseconds = Math.max(parseInt(checkbox.value), MINIMUM_POLL_INTERVAL) * 1000;
|
47
|
+
|
48
|
+
if (this.interval) {
|
49
|
+
clearInterval(this.interval);
|
50
|
+
this.interval = null;
|
51
|
+
}
|
52
|
+
|
53
|
+
if (enabled) {
|
54
|
+
setStorage(STORAGE_KEY, checkbox.value);
|
55
|
+
this.interval = setInterval(LivePoll.refreshPage, pollIntervalMilliseconds);
|
56
|
+
} else {
|
57
|
+
removeStorage(STORAGE_KEY);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
static refreshPage() {
|
62
|
+
fetch(window.location.href)
|
63
|
+
.then(resp => resp.text())
|
64
|
+
.then(LivePoll.updatePageContent);
|
65
|
+
}
|
66
|
+
|
67
|
+
static updatePageContent(newContent) {
|
68
|
+
const domParser = new DOMParser();
|
69
|
+
const newDom = domParser.parseFromString(newContent, "text/html");
|
70
|
+
|
71
|
+
const newElements = newDom.querySelectorAll('[data-live-poll-region]');
|
72
|
+
newElements.forEach((newElement) => {
|
73
|
+
const regionName = newElement.getAttribute('data-live-poll-region');
|
74
|
+
const originalElement = document.querySelector(`[data-live-poll-region="${regionName}"]`);
|
75
|
+
|
76
|
+
originalElement.replaceWith(newElement);
|
77
|
+
});
|
78
|
+
|
79
|
+
renderCharts(false);
|
80
|
+
}
|
81
|
+
}
|
@@ -6,12 +6,12 @@ module GoodJob
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def show
|
9
|
-
@cron_entry = CronEntry.find(params[:
|
9
|
+
@cron_entry = CronEntry.find(params[:cron_key])
|
10
10
|
@jobs_filter = JobsFilter.new(params, @cron_entry.jobs)
|
11
11
|
end
|
12
12
|
|
13
13
|
def enqueue
|
14
|
-
@cron_entry = CronEntry.find(params[:
|
14
|
+
@cron_entry = CronEntry.find(params[:cron_key])
|
15
15
|
@cron_entry.enqueue(Time.current)
|
16
16
|
redirect_back(fallback_location: cron_entries_path, notice: "Cron entry has been enqueued.")
|
17
17
|
end
|
@@ -22,7 +22,7 @@ module GoodJob
|
|
22
22
|
raise ActionController::BadRequest, "#{mass_action} is not a valid mass action" unless mass_action.in?(ACTIONS.keys)
|
23
23
|
|
24
24
|
jobs = if params[:all_job_ids]
|
25
|
-
|
25
|
+
JobsFilter.new(params).filtered_query
|
26
26
|
else
|
27
27
|
job_ids = params.fetch(:job_ids, [])
|
28
28
|
ActiveJobJob.where(active_job_id: job_ids)
|
@@ -49,7 +49,7 @@ module GoodJob
|
|
49
49
|
"No jobs were #{ACTIONS[mass_action]}"
|
50
50
|
end
|
51
51
|
|
52
|
-
|
52
|
+
redirect_back(fallback_location: jobs_path, notice: notice)
|
53
53
|
end
|
54
54
|
|
55
55
|
def show
|
@@ -47,6 +47,7 @@ module GoodJob
|
|
47
47
|
queue_name: params[:queue_name],
|
48
48
|
query: params[:query],
|
49
49
|
state: params[:state],
|
50
|
+
cron_key: params[:cron_key],
|
50
51
|
}.merge(override).delete_if { |_, v| v.blank? }
|
51
52
|
end
|
52
53
|
|
@@ -54,8 +55,9 @@ module GoodJob
|
|
54
55
|
raise NotImplementedError
|
55
56
|
end
|
56
57
|
|
57
|
-
|
58
|
-
|
58
|
+
def filtered_count
|
59
|
+
filtered_query.count
|
60
|
+
end
|
59
61
|
|
60
62
|
private
|
61
63
|
|
@@ -18,6 +18,7 @@ module GoodJob
|
|
18
18
|
query = query.job_class(params[:job_class]) if params[:job_class].present?
|
19
19
|
query = query.where(queue_name: params[:queue_name]) if params[:queue_name].present?
|
20
20
|
query = query.search_text(params[:query]) if params[:query].present?
|
21
|
+
query = query.where(cron_key: params[:cron_key]) if params[:cron_key].present?
|
21
22
|
|
22
23
|
if params[:state]
|
23
24
|
case params[:state]
|
@@ -39,7 +40,7 @@ module GoodJob
|
|
39
40
|
query
|
40
41
|
end
|
41
42
|
|
42
|
-
def
|
43
|
+
def filtered_count
|
43
44
|
filtered_query.unscope(:select).count
|
44
45
|
end
|
45
46
|
|
@@ -1,7 +1,7 @@
|
|
1
|
-
<div class="my-3"
|
1
|
+
<div class="my-3">
|
2
2
|
<div class="table-responsive">
|
3
|
-
<%= form_with(url: mass_update_jobs_path, method: :put, local: true, data: { "checkbox-toggle": "job_ids" }) do |form| %>
|
4
|
-
<table class="table table-hover table-sm mb-0">
|
3
|
+
<%= form_with(url: mass_update_jobs_path(filter.to_params), method: :put, local: true, data: { "checkbox-toggle": "job_ids" }) do |form| %>
|
4
|
+
<table class="table table-hover table-sm mb-0 table-jobs">
|
5
5
|
<thead>
|
6
6
|
<tr>
|
7
7
|
<th><%= check_box_tag('toggle_job_ids', "1", false, data: { "checkbox-toggle-all": "job_ids" }) %></th>
|
@@ -35,6 +35,15 @@
|
|
35
35
|
<%= render_icon "arrow_clockwise" %> All
|
36
36
|
<% end %>
|
37
37
|
</div>
|
38
|
+
</th>
|
39
|
+
</tr>
|
40
|
+
<tr class="d-none" data-checkbox-toggle-show="job_ids">
|
41
|
+
<td class="text-center table-warning" colspan="10">
|
42
|
+
<label>
|
43
|
+
<%= check_box_tag "all_job_ids", 1, false, disabled: true, data: { "checkbox-toggle-show": "job_ids"} %>
|
44
|
+
Apply to all <%= filter.filtered_count %> <%= "job".pluralize(filter.filtered_count) %>.
|
45
|
+
</label>
|
46
|
+
</td>
|
38
47
|
</tr>
|
39
48
|
</thead>
|
40
49
|
<tbody>
|
@@ -1,15 +1,17 @@
|
|
1
1
|
<%= render 'good_job/shared/filter', title: "Jobs", filter: @filter %>
|
2
2
|
<%= render 'good_job/shared/chart', chart_data: GoodJob::ScheduledByQueueChart.new(@filter).data %>
|
3
|
-
<%= render 'good_job/jobs/table', jobs: @filter.records, all_jobs_count: @filter.filtered_query_count %>
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
4
|
+
<div data-live-poll-region="jobs-table">
|
5
|
+
<%= render 'good_job/jobs/table', jobs: @filter.records, filter: @filter %>
|
6
|
+
<% if @filter.records.present? %>
|
7
|
+
<nav aria-label="Job pagination" class="mt-3">
|
8
|
+
<ul class="pagination">
|
9
|
+
<li class="page-item">
|
10
|
+
<%= link_to(@filter.to_params(after_scheduled_at: (@filter.last.scheduled_at || @filter.last.created_at), after_id: @filter.last.id), class: "page-link") do %>
|
11
|
+
Older jobs <span aria-hidden="true">»</span>
|
12
|
+
<% end %>
|
13
|
+
</li>
|
14
|
+
</ul>
|
15
|
+
</nav>
|
16
|
+
<% end %>
|
17
|
+
</div>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<footer class="footer mt-auto py-3 bg-light border-top text-muted small" id="footer" data-
|
1
|
+
<footer class="footer mt-auto py-3 bg-light border-top text-muted small" id="footer" data-live-poll-region="footer">
|
2
2
|
<div class="container-fluid">
|
3
3
|
<div class="row">
|
4
4
|
<div class="col-6">
|
@@ -14,14 +14,14 @@
|
|
14
14
|
<%= link_to t(".cron_schedules"), cron_entries_path, class: ["nav-link", ("active" if controller_name == 'cron_entries')] %>
|
15
15
|
</li>
|
16
16
|
<li class="nav-item">
|
17
|
-
<%= link_to t(".processes"), processes_path, class: ["nav-link", ("active" if
|
17
|
+
<%= link_to t(".processes"), processes_path, class: ["nav-link", ("active" if controller_name == 'processes')] %>
|
18
18
|
</li>
|
19
19
|
</ul>
|
20
20
|
<div class="nav-item pe-2">
|
21
|
-
<
|
22
|
-
|
23
|
-
|
24
|
-
</
|
21
|
+
<label>
|
22
|
+
<%= check_box_tag "live_poll", params.fetch("poll", 30), params[:poll].present? %>
|
23
|
+
<%= t(".live_poll") %>
|
24
|
+
</label>
|
25
25
|
</div>
|
26
26
|
<ul class="navbar-nav">
|
27
27
|
<li class="nav-item dropdown">
|
data/engine/config/routes.rb
CHANGED
@@ -159,7 +159,7 @@ module GoodJob
|
|
159
159
|
alias enable_cron? enable_cron
|
160
160
|
|
161
161
|
def cron
|
162
|
-
env_cron = JSON.parse(ENV
|
162
|
+
env_cron = JSON.parse(ENV.fetch('GOOD_JOB_CRON'), symbolize_names: true) if ENV['GOOD_JOB_CRON'].present?
|
163
163
|
|
164
164
|
options[:cron] ||
|
165
165
|
rails_config[:cron] ||
|
data/lib/good_job/version.rb
CHANGED
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: 2.14.
|
4
|
+
version: 2.14.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: 2022-
|
11
|
+
date: 2022-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -364,7 +364,7 @@ files:
|
|
364
364
|
- engine/app/assets/good_job/modules/charts.js
|
365
365
|
- engine/app/assets/good_job/modules/checkbox_toggle.js
|
366
366
|
- engine/app/assets/good_job/modules/document_ready.js
|
367
|
-
- engine/app/assets/good_job/modules/
|
367
|
+
- engine/app/assets/good_job/modules/live_poll.js
|
368
368
|
- engine/app/assets/good_job/modules/toasts.js
|
369
369
|
- engine/app/assets/good_job/scripts.js
|
370
370
|
- engine/app/assets/good_job/style.css
|
@@ -1,93 +0,0 @@
|
|
1
|
-
/*jshint esversion: 6, strict: false */
|
2
|
-
import renderCharts from "charts";
|
3
|
-
|
4
|
-
// NOTE: this file is a bit disorganized. Please do not use it as a template for how to organize a JS module.
|
5
|
-
|
6
|
-
const DEFAULT_POLL_INTERVAL_SECONDS = 30;
|
7
|
-
const MINIMUM_POLL_INTERVAL = 1000;
|
8
|
-
|
9
|
-
function getStorage(key) {
|
10
|
-
const value = localStorage.getItem('good_job-' + key);
|
11
|
-
|
12
|
-
if (value === 'true') {
|
13
|
-
return true;
|
14
|
-
} else if (value === 'false') {
|
15
|
-
return false;
|
16
|
-
} else {
|
17
|
-
return value;
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
function setStorage(key, value) {
|
22
|
-
localStorage.setItem('good_job-' + key, value);
|
23
|
-
}
|
24
|
-
|
25
|
-
function updatePageContent(newContent) {
|
26
|
-
const domParser = new DOMParser();
|
27
|
-
const parsedDOM = domParser.parseFromString(newContent, "text/html");
|
28
|
-
|
29
|
-
const newElements = parsedDOM.querySelectorAll('[data-gj-poll-replace]');
|
30
|
-
|
31
|
-
for (let i = 0; i < newElements.length; i++) {
|
32
|
-
const newEl = newElements[i];
|
33
|
-
const oldEl = document.getElementById(newEl.id);
|
34
|
-
|
35
|
-
if (oldEl) {
|
36
|
-
oldEl.replaceWith(newEl);
|
37
|
-
}
|
38
|
-
}
|
39
|
-
|
40
|
-
renderCharts(false);
|
41
|
-
}
|
42
|
-
|
43
|
-
function refreshPage() {
|
44
|
-
fetch(window.location.href)
|
45
|
-
.then(resp => resp.text())
|
46
|
-
.then(updatePageContent);
|
47
|
-
}
|
48
|
-
|
49
|
-
const Poller = {
|
50
|
-
start: () => {
|
51
|
-
Poller.updateSettings();
|
52
|
-
Poller.pollUpdates();
|
53
|
-
|
54
|
-
const checkbox = document.querySelector('input[name="toggle-poll"]');
|
55
|
-
checkbox.addEventListener('change', Poller.togglePoll)
|
56
|
-
},
|
57
|
-
|
58
|
-
togglePoll: (event) => {
|
59
|
-
Poller.pollEnabled = event.currentTarget.checked;
|
60
|
-
setStorage('pollEnabled', Poller.pollEnabled);
|
61
|
-
},
|
62
|
-
|
63
|
-
updateSettings: () => {
|
64
|
-
const queryString = window.location.search;
|
65
|
-
const urlParams = new URLSearchParams(queryString);
|
66
|
-
|
67
|
-
if (urlParams.has('poll')) {
|
68
|
-
const parsedInterval = (parseInt(urlParams.get('poll')) || DEFAULT_POLL_INTERVAL_SECONDS) * 1000;
|
69
|
-
Poller.pollInterval = Math.max(parsedInterval, MINIMUM_POLL_INTERVAL);
|
70
|
-
setStorage('pollInterval', Poller.pollInterval);
|
71
|
-
|
72
|
-
Poller.pollEnabled = true;
|
73
|
-
} else {
|
74
|
-
Poller.pollInterval = getStorage('pollInterval') || (DEFAULT_POLL_INTERVAL_SECONDS * 1000);
|
75
|
-
Poller.pollEnabled = getStorage('pollEnabled') || false;
|
76
|
-
}
|
77
|
-
|
78
|
-
document.getElementById('toggle-poll').checked = Poller.pollEnabled;
|
79
|
-
},
|
80
|
-
|
81
|
-
pollUpdates: () => {
|
82
|
-
setTimeout(() => {
|
83
|
-
if (Poller.pollEnabled === true) {
|
84
|
-
refreshPage();
|
85
|
-
Poller.pollUpdates();
|
86
|
-
} else {
|
87
|
-
Poller.pollUpdates();
|
88
|
-
}
|
89
|
-
}, Poller.pollInterval);
|
90
|
-
},
|
91
|
-
};
|
92
|
-
|
93
|
-
export { Poller as default };
|