Merge pull request #583 from knu/highlight_new_events

Make event-indicator a link to the events page, with new events highlighted
This commit is contained in:
Akinori MUSHA 2014-10-27 12:29:47 +09:00
commit 9b5510131a
7 changed files with 115 additions and 20 deletions

View file

@ -1,10 +1,15 @@
$ ->
firstEventCount = null
sinceId = null
previousJobs = null
if $(".job-indicator").length
check = ->
$.getJSON "/worker_status", (json) ->
query =
if sinceId?
'?since_id=' + sinceId
else
''
$.getJSON "/worker_status" + query, (json) ->
for method in ['pending', 'awaiting_retry', 'recent_failures']
count = json[method]
elem = $(".job-indicator[role=#{method}]")
@ -23,16 +28,17 @@ $ ->
if elem.is(":visible")
elem.tooltip('destroy').fadeOut()
firstEventCount = json.event_count unless firstEventCount?
if firstEventCount? && json.event_count > firstEventCount
if sinceId? && json.event_count > 0
$("#event-indicator").tooltip('destroy').
tooltip(title: "Click to reload", delay: 0, placement: "bottom", trigger: "hover").
tooltip(title: "Click to see the events", delay: 0, placement: "bottom", trigger: "hover").
find('a').attr(href: json.events_url).end().
fadeIn().
find(".number").
text(json.event_count - firstEventCount)
text(json.event_count)
else
$("#event-indicator").tooltip('destroy').fadeOut()
sinceId ?= json.max_id
currentJobs = [json.pending, json.awaiting_retry, json.recent_failures]
if document.location.pathname == '/jobs' && $(".modal[aria-hidden=false]").length == 0 && previousJobs? && previousJobs.join(',') != currentJobs.join(',')
$.get '/jobs', (data) =>
@ -42,7 +48,3 @@ $ ->
window.workerCheckTimeout = setTimeout check, 2000
check()
$("#event-indicator a").on "click", (e) ->
e.preventDefault()
window.location.reload()

View file

@ -20,6 +20,20 @@
}
}
.table-striped > tbody > tr.hl {
&:nth-child(odd) {
> td, > th {
background-color: #ffeecc;
}
}
&:nth-child(even) {
> td, > th {
background-color: #f9e8c6;
}
}
}
table.events {
.payload {
color: #999;

View file

@ -1,12 +1,32 @@
class WorkerStatusController < ApplicationController
def show
start = Time.now.to_f
render :json => {
:pending => Delayed::Job.where("run_at <= ? AND locked_at IS NULL AND attempts = 0", Time.now).count,
:awaiting_retry => Delayed::Job.where("failed_at IS NULL AND attempts > 0").count,
:recent_failures => Delayed::Job.where("failed_at IS NOT NULL AND failed_at > ?", 5.days.ago).count,
:event_count => current_user.events.count,
:compute_time => Time.now.to_f - start
start = Time.now
events = current_user.events
if params[:since_id].present?
since_id = params[:since_id].to_i
events = events.where('id > ?', since_id)
end
result = events.select('COUNT(id) AS count', 'MIN(id) AS min_id', 'MAX(id) AS max_id').first
count, min_id, max_id = result.count, result.min_id, result.max_id
case max_id
when nil
when min_id
events_url = events_path(hl: max_id)
else
events_url = events_path(hl: "#{min_id}-#{max_id}")
end
render json: {
pending: Delayed::Job.pending.where("run_at <= ?", start).count,
awaiting_retry: Delayed::Job.awaiting_retry.count,
recent_failures: Delayed::Job.failed.where('failed_at > ?', 5.days.ago).count,
event_count: count,
max_id: max_id || 0,
events_url: events_url,
compute_time: Time.now - start
}
end
end

View file

@ -71,4 +71,25 @@ module ApplicationHelper
service_label_text(service)
].join.html_safe, class: "label label-default label-service service-#{service.provider}"
end
def highlighted?(id)
@highlighted_ranges ||=
case value = params[:hl].presence
when String
value.split(/,/).flat_map { |part|
case part
when /\A(\d+)\z/
(part.to_i)..(part.to_i)
when /\A(\d+)?-(\d+)?\z/
($1 ? $1.to_i : 1)..($2 ? $2.to_i : Float::INFINITY)
else
[]
end
}
else
[]
end
@highlighted_ranges.any? { |range| range.cover?(id) }
end
end

View file

@ -18,7 +18,7 @@
<% @events.each do |event| %>
<% next unless event.agent %>
<tr>
<%= content_tag :tr, class: (highlighted?(event.id) ? 'hl' : nil) do %>
<td><%= link_to event.agent.name, agent_path(event.agent) %></td>
<td title='<%= event.created_at %>'><%= time_ago_in_words event.created_at %> ago</td>
<td class='payload'><%= truncate event.payload.to_json, :length => 90, :omission => "" %></td>
@ -29,12 +29,12 @@
<%= link_to 'Delete', event_path(event), method: :delete, data: { confirm: 'Are you sure?' }, class: "btn btn-default" %>
</div>
</td>
</tr>
<% end %>
<% end %>
</table>
</div>
<%= paginate @events, :theme => 'twitter-bootstrap-3' %>
<%= paginate @events, params: params.slice(:hl), theme: 'twitter-bootstrap-3' %>
<br />

View file

@ -7,3 +7,9 @@ Delayed::Worker.delay_jobs = !Rails.env.test?
# Delayed::Worker.logger = Logger.new(Rails.root.join('log', 'delayed_job.log'))
# Delayed::Worker.logger.level = Logger::DEBUG
class Delayed::Job
scope :pending, ->{ where("locked_at IS NULL AND attempts = 0") }
scope :awaiting_retry, ->{ where("failed_at IS NULL AND attempts > 0") }
scope :failed, -> { where("failed_at IS NOT NULL") }
end

View file

@ -143,4 +143,36 @@ describe ApplicationHelper do
expect(elem).to be_a Nokogiri::XML::Element
end
end
describe '#highlighted?' do
it 'understands hl=6-8' do
stub(params).[](:hl) { '6-8' }
expect((1..10).select { |i| highlighted?(i) }).to eq [6, 7, 8]
end
it 'understands hl=1,3-4,9' do
stub(params).[](:hl) { '1,3-4,9' }
expect((1..10).select { |i| highlighted?(i) }).to eq [1, 3, 4, 9]
end
it 'understands hl=8-' do
stub(params).[](:hl) { '8-' }
expect((1..10).select { |i| highlighted?(i) }).to eq [8, 9, 10]
end
it 'understands hl=-2' do
stub(params).[](:hl) { '-2' }
expect((1..10).select { |i| highlighted?(i) }).to eq [1, 2]
end
it 'understands hl=-' do
stub(params).[](:hl) { '-' }
expect((1..10).select { |i| highlighted?(i) }).to eq [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
end
it 'is OK with no hl' do
stub(params).[](:hl) { nil }
expect((1..10).select { |i| highlighted?(i) }).to be_empty
end
end
end