mirror of
https://github.com/mperham/sidekiq.git
synced 2022-11-09 13:52:34 -05:00
Persist live poll status in browser localStorage (#4976)
* Persist live poll status in browser localStorage * Prefix localStorage variables with 'sidekiq' * Minor fix for default handling in localStorage timeInterval parsing
This commit is contained in:
parent
8e36432662
commit
84dd20d397
8 changed files with 80 additions and 58 deletions
|
@ -70,17 +70,6 @@ module Sidekiq
|
|||
@head_html.join if defined?(@head_html)
|
||||
end
|
||||
|
||||
def poll_path
|
||||
if current_path != "" && params["poll"]
|
||||
path = root_path + current_path
|
||||
query_string = to_query_string(params.slice(*params.keys - %w[page poll]))
|
||||
path += "?#{query_string}" unless query_string.empty?
|
||||
path
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def text_direction
|
||||
get_locale["TextDirection"] || "ltr"
|
||||
end
|
||||
|
@ -203,7 +192,7 @@ module Sidekiq
|
|||
[score.to_f, jid]
|
||||
end
|
||||
|
||||
SAFE_QPARAMS = %w[page poll direction]
|
||||
SAFE_QPARAMS = %w[page direction]
|
||||
|
||||
# Merge options with current params, filter safe params, and stringify to query string
|
||||
def qparams(options)
|
||||
|
|
|
@ -428,12 +428,6 @@ describe Sidekiq::Web do
|
|||
assert_match(/#{msg['args'][2]}/, last_response.body)
|
||||
end
|
||||
|
||||
it 'calls updatePage() once when polling' do
|
||||
get '/busy?poll=true'
|
||||
assert_equal 200, last_response.status
|
||||
assert_equal 1, last_response.body.scan('data-poll-path="/busy').count
|
||||
end
|
||||
|
||||
it 'escape job args and error messages' do
|
||||
# on /retries page
|
||||
params = add_xss_retry
|
||||
|
@ -647,12 +641,6 @@ describe Sidekiq::Web do
|
|||
assert_equal 200, last_response.status
|
||||
assert_match(/#{params.first['args'][2]}/, last_response.body)
|
||||
end
|
||||
|
||||
it 'handles bad query input' do
|
||||
get '/queues/foo?page=B<H'
|
||||
assert_equal 200, last_response.status
|
||||
assert_match(/B%3CH/, last_response.body)
|
||||
end
|
||||
end
|
||||
|
||||
def add_scheduled
|
||||
|
|
|
@ -109,4 +109,19 @@ class TestWebHelpers < Minitest::Test
|
|||
s = o.display_args(nil)
|
||||
assert_equal "Invalid job payload, args is nil", s
|
||||
end
|
||||
|
||||
def test_to_query_string_escapes_bad_query_input
|
||||
obj = Helpers.new
|
||||
assert_equal "page=B%3CH", obj.to_query_string("page" => "B<H")
|
||||
end
|
||||
|
||||
def test_qparams_string_escapes_bad_query_input
|
||||
obj = Helpers.new
|
||||
obj.instance_eval do
|
||||
def params
|
||||
{ "direction" => "H>B" }
|
||||
end
|
||||
end
|
||||
assert_equal "direction=H%3EB&page=B%3CH", obj.qparams("page" => "B<H")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,13 +16,9 @@
|
|||
|
||||
Sidekiq = {};
|
||||
|
||||
$(function() {
|
||||
var pollpath = $('body').data('poll-path');
|
||||
if (pollpath != "") {
|
||||
var ti = parseInt(localStorage.timeInterval) || 2000;
|
||||
setTimeout(function(){updatePage(pollpath)}, ti);
|
||||
}
|
||||
var livePollTimer = null;
|
||||
|
||||
$(function() {
|
||||
$(document).on('click', '.check_all', function() {
|
||||
$('input[type=checkbox]', $(this).closest('table')).prop('checked', this.checked);
|
||||
});
|
||||
|
@ -36,6 +32,26 @@ $(function() {
|
|||
});
|
||||
|
||||
updateFuzzyTimes($('body').data('locale'));
|
||||
|
||||
if ($(".live-poll").length > 0) { // set up live poll only when button is present
|
||||
$(document).on("click", ".live-poll", function() {
|
||||
if (localStorage.sidekiqLivePoll == "enabled") {
|
||||
localStorage.sidekiqLivePoll = "disabled";
|
||||
clearTimeout(livePollTimer);
|
||||
livePollTimer = null;
|
||||
} else {
|
||||
localStorage.sidekiqLivePoll = "enabled";
|
||||
livePollCallback();
|
||||
}
|
||||
|
||||
updateLivePollButton();
|
||||
});
|
||||
|
||||
updateLivePollButton();
|
||||
if (localStorage.sidekiqLivePoll == "enabled") {
|
||||
scheduleLivePoll();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function updateFuzzyTimes(locale) {
|
||||
|
@ -50,11 +66,35 @@ function updateFuzzyTimes(locale) {
|
|||
t.cancel();
|
||||
}
|
||||
|
||||
function updatePage(url) {
|
||||
function updateLivePollButton() {
|
||||
if (localStorage.sidekiqLivePoll == "enabled") {
|
||||
$('.live-poll-stop').show();
|
||||
$('.live-poll-start').hide();
|
||||
} else {
|
||||
$('.live-poll-start').show();
|
||||
$('.live-poll-stop').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function livePollCallback() {
|
||||
clearTimeout(livePollTimer);
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
url: document.url,
|
||||
dataType: 'html'
|
||||
}).done(function(data) {
|
||||
}).done(
|
||||
replacePage
|
||||
).complete(
|
||||
scheduleLivePoll
|
||||
)
|
||||
}
|
||||
|
||||
function scheduleLivePoll() {
|
||||
let ti = parseInt(localStorage.sidekiqTimeInterval) || 5000;
|
||||
livePollTimer = setTimeout(livePollCallback, ti);
|
||||
}
|
||||
|
||||
function replacePage(data) {
|
||||
$data = $(data)
|
||||
|
||||
var $page = $data.filter('#page')
|
||||
|
@ -64,13 +104,6 @@ function updatePage(url) {
|
|||
$('.status').replaceWith($header_status)
|
||||
|
||||
updateFuzzyTimes($('body').data('locale'));
|
||||
|
||||
var ti = parseInt(localStorage.timeInterval) || 2000;
|
||||
setTimeout(function(){updatePage(url)}, ti)
|
||||
}).fail(function() {
|
||||
var ti = parseInt(localStorage.timeInterval) || 2000;
|
||||
setTimeout(function(){updatePage(url)}, ti)
|
||||
})
|
||||
}
|
||||
|
||||
$(function() {
|
||||
|
|
|
@ -17,7 +17,7 @@ var nodes=vis.selectAll("path").data(series.stack.filter(function(d){return d.y!
|
|||
|
||||
var poller;
|
||||
var realtimeGraph = function(updatePath) {
|
||||
var timeInterval = parseInt(localStorage.timeInterval || '5000');
|
||||
var timeInterval = parseInt(localStorage.sidekiqTimeInterval) || 5000;
|
||||
var graphElement = document.getElementById("realtime");
|
||||
|
||||
var graph = new Rickshaw.Graph( {
|
||||
|
@ -246,14 +246,14 @@ var setSliderLabel = function(val) {
|
|||
$(function(){
|
||||
renderGraphs();
|
||||
|
||||
if (typeof localStorage.timeInterval !== 'undefined'){
|
||||
$('div.interval-slider input').val(localStorage.timeInterval);
|
||||
setSliderLabel(localStorage.timeInterval);
|
||||
if (typeof localStorage.sidekiqTimeInterval !== 'undefined'){
|
||||
$('div.interval-slider input').val(localStorage.sidekiqTimeInterval);
|
||||
setSliderLabel(localStorage.sidekiqTimeInterval);
|
||||
}
|
||||
|
||||
$(document).on('change', 'div.interval-slider input', function(){
|
||||
clearInterval(poller);
|
||||
localStorage.timeInterval = $(this).val();
|
||||
localStorage.sidekiqTimeInterval = $(this).val();
|
||||
setSliderLabel($(this).val());
|
||||
resetGraphs();
|
||||
renderGraphs();
|
||||
|
|
|
@ -98,10 +98,10 @@ header.row .pagination {
|
|||
.poll-wrapper {
|
||||
margin: 9px;
|
||||
}
|
||||
#live-poll.active {
|
||||
.live-poll.active {
|
||||
background-color: #009300;
|
||||
}
|
||||
#live-poll.active:hover {
|
||||
.live-poll.active:hover {
|
||||
background-color: #777;
|
||||
}
|
||||
.summary_bar ul {
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
<% if current_path != '' %>
|
||||
<% if params[:poll] %>
|
||||
<a id="live-poll" class="btn btn-primary active" href="<%= root_path + current_path %>"><%= t('StopPolling') %></a>
|
||||
<% else %>
|
||||
<a id="live-poll" class="btn btn-primary" href="<%= root_path + current_path %>?<%= qparams(poll: true) %>"><%= t('LivePoll') %></a>
|
||||
<% end %>
|
||||
<a class="live-poll-start live-poll btn btn-primary"><%= t('LivePoll') %></a>
|
||||
<a class="live-poll-stop live-poll btn btn-primary active"><%= t('StopPolling') %></a>
|
||||
<% end %>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<meta name="google" content="notranslate" />
|
||||
<%= display_custom_head %>
|
||||
</head>
|
||||
<body class="admin" data-poll-path="<%= poll_path %>" data-locale="<%= locale %>">
|
||||
<body class="admin" data-locale="<%= locale %>">
|
||||
<%= erb :_nav %>
|
||||
<div id="page">
|
||||
<div class="container">
|
||||
|
|
Loading…
Add table
Reference in a new issue