1
0
Fork 0
mirror of https://github.com/mperham/sidekiq.git synced 2022-11-09 13:52:34 -05:00

Make Sidekiq Web UI RTL-friendly (#3381)

* Unminify rickshaw graph CSS so we can maintain it

* Initial BiDi support for the Web UI

BiDi means the web app can serve both LTR and RTL languages at the same time.

1. Bootstrap-RTL overrides Bootstrap 3.3 styles for RTL clients
2. Application CSS was preprocessed thru rtlcss and then hand-trimmed to contain only RTL-specific directives.
3. Dashboard was tweaked to hardcode LTR for footer and polling gadget

* Vendor bootstrap-rtl.css

* Various RTL style fixes, need to flip all pull-* elements

* Upgrade Rickshaw to latest, remove dupe CSS

* Add Arabic language (credit to Milena Novakova)
Add Hebrew placeholder
Added dir attribute to html tag

* changes

* Clean up HTTP header generation, add Content-Language response header

* Use correct locale for hebrew
This commit is contained in:
Mike Perham 2017-03-16 13:51:29 -07:00 committed by GitHub
parent 5806792716
commit ed485e47e4
23 changed files with 811 additions and 54 deletions

View file

@ -30,6 +30,9 @@ versions of Ruby and Rails.
**ST**o**P**) instead of USR1 as USR1 is not available on JRuby. **ST**o**P**) instead of USR1 as USR1 is not available on JRuby.
USR1 will continue to be supported in Sidekiq 5.x for backwards USR1 will continue to be supported in Sidekiq 5.x for backwards
compatibility and will be removed in Sidekiq 6.x. [#3302] compatibility and will be removed in Sidekiq 6.x. [#3302]
* The Web UI is now bi-directional - it can render either LTR
(left-to-right) or RTL languages. With this change, Farsi, Arabic
and Hebrew are all now officially supported! [#3381]
* Rails 3.2 is no longer supported. * Rails 3.2 is no longer supported.
* Ruby 2.0 and Ruby 2.1 are no longer supported. Ruby 2.2.2+ is required. * Ruby 2.0 and Ruby 2.1 are no longer supported. Ruby 2.2.2+ is required.
* Jobs which can't be parsed due to invalid JSON are now pushed * Jobs which can't be parsed due to invalid JSON are now pushed

View file

@ -14,6 +14,7 @@ Sidekiq::Middleware::Server::Logging -> Sidekiq::JobLogging
- Quieting Sidekiq is now done via the TSTP signal, the USR1 signal is deprecated. - Quieting Sidekiq is now done via the TSTP signal, the USR1 signal is deprecated.
- The `delay` extension APIs are no longer available by default, you - The `delay` extension APIs are no longer available by default, you
must opt into them. must opt into them.
- The Web UI is now BiDi and can render in Arabic, Farsi and Hebrew.
- Rails 3.2 and Ruby 2.0 and 2.1 are no longer supported. - Rails 3.2 and Ruby 2.0 and 2.1 are no longer supported.
- Please see the [5.0 Upgrade notes](5.0-Upgrade.md) for more detail. - Please see the [5.0 Upgrade notes](5.0-Upgrade.md) for more detail.

View file

@ -39,10 +39,6 @@ module Sidekiq
env[RACK_SESSION] env[RACK_SESSION]
end end
def content_type(type)
@type = type
end
def erb(content, options = {}) def erb(content, options = {})
if content.kind_of? Symbol if content.kind_of? Symbol
unless respond_to?(:"_erb_#{content}") unless respond_to?(:"_erb_#{content}")

View file

@ -274,19 +274,14 @@ module Sidekiq
resp = case resp resp = case resp
when Array when Array
resp resp
when Integer
[resp, {}, []]
else else
type_header = case action.type headers = {
when :json "Content-Type" => "text/html",
{ "Content-Type" => "application/json", "Cache-Control" => "no-cache" } "Cache-Control" => "no-cache",
when String "Content-Language" => action.locale,
{ "Content-Type" => (action.type || "text/html"), "Cache-Control" => "no-cache" } }
else
{ "Content-Type" => "text/html", "Cache-Control" => "no-cache" }
end
[200, type_header, [resp]] [200, headers, [resp]]
end end
resp[1] = resp[1].dup resp[1] = resp[1].dup

View file

@ -65,6 +65,14 @@ module Sidekiq
end end
end end
def text_direction
get_locale['TextDirection'] || 'ltr'
end
def rtl?
text_direction == 'rtl'
end
# Given a browser request Accept-Language header like # Given a browser request Accept-Language header like
# "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2", this function # "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2", this function
# will return "fr" since that's the first code with a matching # will return "fr" since that's the first code with a matching
@ -144,7 +152,7 @@ module Sidekiq
def relative_time(time) def relative_time(time)
stamp = time.getutc.iso8601 stamp = time.getutc.iso8601
%{<time title="#{stamp}" datetime="#{stamp}">#{time}</time>} %{<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>}
end end
def job_params(job, score) def job_params(job, score)

View file

@ -3,7 +3,7 @@ source 'https://rubygems.org'
gem 'appraisal' gem 'appraisal'
gem 'pry' gem 'pry'
gem 'sidekiq', :path => '..' gem 'sidekiq', :path => '..'
gem 'rails', '5.0.1' gem 'rails', '5.0.2'
platforms :ruby do platforms :ruby do
gem 'sqlite3' gem 'sqlite3'

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,246 @@
.navbar-right {
float: left !important;
}
footer .edits {
margin-right: unset;
margin-left: 40px;
}
.summary_bar .status {
margin-left: unset;
margin-right: 10px;
}
@media (max-width: 767px) and (min-width: 400px) {
.summary_bar ul .desc {
text-align: right;
}
.summary_bar ul .count {
text-align: left;
}
}
@media (max-width: 979px) and (min-width: 768px) {
}
.summary_bar ul .count {
float: left;
}
form .btn {
margin-right: unset;
margin-left: 5px;
}
form .btn-group .btn {
margin-right: unset;
margin-left: 1px;
}
@media (max-width: 768px) {
.navbar.navbar-fixed-top ul {
margin-right: unset;
margin-left: -15px!important;
}
}
@media (width: 768px) {
.navbar .poll-wrapper {
margin: 4px 0 0 4px;
}
.navbar .dropdown-menu a {
text-align: right;
}
}
.navbar-footer .navbar ul.nav a.navbar-brand {
padding: 0 0 0 15px;
}
.navbar-fixed-bottom li {
margin-right: unset;
margin-left: 20px;
}
.status-active {
background-position: 100% 0;
}
.status-idle {
background-position: 100% -54px;
}
.stat {
float: right;
margin-right: unset;
margin-left: 20px;
}
.stat:last-child {
margin-left: 0;
}
@media (max-width: 767px) {
.stat {
float: right;
margin-right: unset;
margin-left: 10px;
text-align: right;
}
.stat h3{
float: left;
margin: 5px 5px 5px 10px;
}
.stat p{
font-size: 1em;
margin: 5px 10px 5px 5px;
}
}
/* Dashboard
********************************** */
div.dashboard h3 {
float: right;
}
div.interval-slider {
float: left;
}
#realtime-legend,
#history-legend {
text-align: right;
float: left;
}
#realtime-legend .timestamp,
#history-legend .timestamp {
text-align: left;
}
#realtime-legend .line,
#history-legend .line {
margin: 0 20px 0 0;
}
#realtime-legend .swatch,
#history-legend .swatch {
margin: 0 0 0 8px;
}
/* Beacon
********************************** */
.beacon .dot,
.beacon .ring {
right: 50%;
}
.beacon .dot {
margin: -5px -5px 0 0;
}
.beacon .ring {
margin: -14px -14px 0 0;
}
.history-heading {
padding-right: unset;
padding-left: 15px;
}
@media (max-width: 767px) {
.navbar.navbar-fixed-top ul {
margin-left: 0;
}
.navbar.navbar-fixed-top li {
margin-left: 0;
}
.navbar.navbar-fixed-bottom ul {
margin-left: 0;
}
.navbar.navbar-fixed-bottom li {
margin-left: 0;
}
}
@media (max-width: 500px) {
.navbar-footer .navbar ul.nav a.navbar-brand {
padding-right: unset;
padding-left: 5px;
}
}
/* Rickshaw */
.rickshaw_graph .detail .x_label.left {
right: 0
}
.rickshaw_graph .detail .x_label.right {
left: 0
}
.rickshaw_graph .detail .item.left {
right: 0
}
.rickshaw_graph .detail .item.right {
left: 0
}
.rickshaw_graph .detail .item.left:after {
left: 0;
right: -5px;
border-right-color: unset;
border-left-color: rgba(0, 0, 0, .8);
border-right-width: 0;
border-left-width: unset;
}
.rickshaw_graph .detail .item.right:after {
right: 0;
left: -5px;
border-left-color: unset;
border-right-color: rgba(0, 0, 0, .8);
border-left-width: 0;
border-right-width: unset;
}
.rickshaw_graph .detail .dot {
margin-right: -3px;
margin-left: unset;
}
.rickshaw_graph .x_tick {
border-left: unset;
border-right: 1px dotted rgba(0, 0, 0, .2);
}
.rickshaw_graph .x_tick .title {
margin-right: 3px;
margin-left: unset;
}
.rickshaw_annotation_timeline .annotation {
margin-right: -2px;
margin-left: unset;
}
.rickshaw_graph .annotation_line {
border-right: 2px solid rgba(0, 0, 0, .3);
border-left: unset;
}
.rickshaw_annotation_timeline .annotation .content {
left: unset;
right: -11px;
}
.rickshaw_graph .x_tick.glow .title,
.rickshaw_graph .y_ticks.glow text {
text-shadow: 1px 1px 0 rgba(255, 255, 255, .1), -1px -1px 0 rgba(255, 255, 255, .1), -1px 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1), 0 -1px 0 rgba(255, 255, 255, .1), -1px 0 0 rgba(255, 255, 255, .1), 1px 0 0 rgba(255, 255, 255, .1), 1px -1px 0 rgba(255, 255, 255, .1)
}
.rickshaw_graph .x_tick.inverse .title,
.rickshaw_graph .y_ticks.inverse text {
text-shadow: 1px 1px 0 rgba(0, 0, 0, .8), -1px -1px 0 rgba(0, 0, 0, .8), -1px 1px 0 rgba(0, 0, 0, .8), 0 1px 0 rgba(0, 0, 0, .8), 0 -1px 0 rgba(0, 0, 0, .8), -1px 0 0 rgba(0, 0, 0, .8), 1px 0 0 rgba(0, 0, 0, .8), 1px -1px 0 rgba(0, 0, 0, .8)
}
.rickshaw_legend .line {
padding-left: 15px;
padding-right: unset;
}
.rickshaw_legend .line .swatch {
margin-left: 3px;
margin-right: unset;
}
.rickshaw_legend .action {
margin-left: .2em;
margin-right: unset;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

80
web/locales/ar.yml Normal file
View file

@ -0,0 +1,80 @@
# elements like %{queue} are variables and should not be translated
ar:
TextDirection: 'rtl'
Dashboard: لوحة القيادة
Status: حالة
Time: وقت
Namespace: مساحة الأسماء
Realtime: راهن
History: تاريخ
Busy: مصروف
Processed: مصنوع
Failed: فشل
Scheduled: مبرمج
Retries: محاولة
Enqueued: بالدور
Worker: عامل
LivePoll: استجواب
StopPolling: استجوب على الملكان
Queue: دورة
Class: فىة
Job: وظيفة
Arguments: براهين
Extras: اضافة
Started: ابتداء
ShowAll: عرض كل الشي
CurrentMessagesInQueue: الأعمال الجارية في <span class='title'>%{queue}</span>
AddToQueue: الإضافة إلى الدور
AreYouSureDeleteJob: ا تتأكد من العمل؟
AreYouSureDeleteQueue: ا تتأكد من إزالة %{queue} الدور؟
Delete: حذف
Queues: دورات
Size: حجم
Actions: اجراءات
NextRetry: المحاولة القادمة
RetryCount: عدد إعادة المحاولة
RetryNow: إعادة المحاولة الآن
Kill: ابطل
LastRetry: المحاولة الأخيرة
OriginallyFailed: فشل أصلا
AreYouSure: هل انت متأكد؟
DeleteAll: حذف كل شي
RetryAll: عاد كل شي
NoRetriesFound: لم وجد المحاولات
Error: خطأ
ErrorClass: طبقة الخطأ
ErrorMessage: رسالة الخطأ
ErrorBacktrace: الخطأ العودة التتبع
GoBack: تقهقر
NoScheduledFound: لم وجد المشاكل المبرمجة
When: متى
ScheduledJobs: المشاكل المبرمجة
idle: اشل
active: عامل
Version: تفريعة
Connections: اشتراك
MemoryUsage: استخدام الذاكرة
PeakMemoryUsage: ذروة استخدام الذاكرة
Uptime: أجال عامل
OneWeek: أسبوع
OneMonth: شهر
ThreeMonths: ثلاثة أشهر
SixMonths: ستة أشهر
Failures: فشل
DeadJobs: وظائف الميتة
NoDeadJobsFound: لم وجد وظائف الميتة
Dead: ميتة
Processes: عملية
Thread: خيط
Threads: خيوط
Jobs: وظائف
Paused: ركزة
Stop: خلاص
Quiet: هدوء
StopAll: خلاص كل الشي
QuietAll: الهدوء فقط
PollingInterval: استقصاء
Plugins: الإضافات
NotYetEnqueued: ليس في دورة حتى
CreatedAt: أنشئت في
BackToApp: العودة إلى التطبيق

View file

@ -1,5 +1,6 @@
# elements like %{queue} are variables and should not be translated # elements like %{queue} are variables and should not be translated
fa: # <---- change this to your locale code fa: # <---- change this to your locale code
TextDirection: 'rtl'
Dashboard: داشبورد Dashboard: داشبورد
Status: اعلان Status: اعلان
Time: رمان Time: رمان

79
web/locales/he.yml Normal file
View file

@ -0,0 +1,79 @@
he:
TextDirection: 'rtl'
Dashboard: Dashboard
Status: Status
Time: Time
Namespace: Namespace
Realtime: Real-time
History: History
Busy: Busy
Processed: Processed
Failed: Failed
Scheduled: Scheduled
Retries: Retries
Enqueued: Enqueued
Worker: Worker
LivePoll: Live Poll
StopPolling: Stop Polling
Queue: Queue
Class: Class
Job: Job
Arguments: Arguments
Extras: Extras
Started: Started
ShowAll: Show All
CurrentMessagesInQueue: Current jobs in <span class='title'>%{queue}</span>
Delete: Delete
AddToQueue: Add to queue
AreYouSureDeleteJob: Are you sure you want to delete this job?
AreYouSureDeleteQueue: Are you sure you want to delete the %{queue} queue?
Queues: Queues
Size: Size
Actions: Actions
NextRetry: Next Retry
RetryCount: Retry Count
RetryNow: Retry Now
Kill: Kill
LastRetry: Last Retry
OriginallyFailed: Originally Failed
AreYouSure: Are you sure?
DeleteAll: Delete All
RetryAll: Retry All
NoRetriesFound: No retries were found
Error: Error
ErrorClass: Error Class
ErrorMessage: Error Message
ErrorBacktrace: Error Backtrace
GoBack: ← Back
NoScheduledFound: No scheduled jobs were found
When: When
ScheduledJobs: Scheduled Jobs
idle: idle
active: active
Version: Version
Connections: Connections
MemoryUsage: Memory Usage
PeakMemoryUsage: Peak Memory Usage
Uptime: Uptime (days)
OneWeek: 1 week
OneMonth: 1 month
ThreeMonths: 3 months
SixMonths: 6 months
Failures: Failures
DeadJobs: Dead Jobs
NoDeadJobsFound: No dead jobs were found
Dead: Dead
Processes: Processes
Thread: Thread
Threads: Threads
Jobs: Jobs
Paused: Paused
Stop: Stop
Quiet: Quiet
StopAll: Stop All
QuietAll: Quiet All
PollingInterval: Polling interval
Plugins: Plugins
NotYetEnqueued: Not yet enqueued
CreatedAt: Created At
BackToApp: Back to App

View file

@ -1,4 +1,4 @@
<div class="navbar navbar-fixed-bottom navbar-inverse"> <div class="navbar navbar-fixed-bottom navbar-inverse ltr">
<div class="navbar-inner"> <div class="navbar-inner">
<div class="container text-center"> <div class="container text-center">
<ul class="nav"> <ul class="nav">

View file

@ -53,7 +53,7 @@
</ul> </ul>
<ul class="nav navbar-nav navbar-right navbar-livereload" data-navbar="static"> <ul class="nav navbar-nav navbar-right navbar-livereload" data-navbar="static">
<li> <li>
<div class="poll-wrapper pull-right"> <div class="poll-wrapper">
<%= erb :_poll_link %> <%= erb :_poll_link %>
<% if Sidekiq::Web.app_url %> <% if Sidekiq::Web.app_url %>
<a class="btn btn-inverse" href="<%= Sidekiq::Web.app_url %>"><%= t('BackToApp') %></a> <a class="btn btn-inverse" href="<%= Sidekiq::Web.app_url %>"><%= t('BackToApp') %></a>

View file

@ -1,5 +1,5 @@
<% if @total_size > @count %> <% if @total_size > @count %>
<ul class="pagination pull-right"> <ul class="pagination pull-right flip">
<li class="<%= 'disabled' if @current_page == 1 %>"> <li class="<%= 'disabled' if @current_page == 1 %>">
<a href="<%= url %>?page=1">&laquo;</a> <a href="<%= url %>?page=1">&laquo;</a>
</li> </li>

View file

@ -1,11 +1,11 @@
<div class="row header"> <div class="row header">
<div class="col-sm-8 pull-left"> <div class="col-sm-8 pull-left flip">
<h3><%= t('Processes') %></h3> <h3><%= t('Processes') %></h3>
</div> </div>
<div class="col-sm-4 pull-right"> <div class="col-sm-4 pull-right flip">
<form method="POST" class="warning-messages"> <form method="POST" class="warning-messages">
<%= csrf_tag %> <%= csrf_tag %>
<div class="btn-group pull-right"> <div class="btn-group pull-right flip">
<button class="btn btn-warn" type="submit" name="quiet" value="1" data-confirm="<%= t('AreYouSure') %>"><%= t('QuietAll') %></button> <button class="btn btn-warn" type="submit" name="quiet" value="1" data-confirm="<%= t('AreYouSure') %>"><%= t('QuietAll') %></button>
<button class="btn btn-danger" type="submit" name="stop" value="1" data-confirm="<%= t('AreYouSure') %>"><%= t('StopAll') %></button> <button class="btn btn-danger" type="submit" name="stop" value="1" data-confirm="<%= t('AreYouSure') %>"><%= t('StopAll') %></button>
</div> </div>
@ -41,7 +41,7 @@
<td><%= process['concurrency'] %></td> <td><%= process['concurrency'] %></td>
<td><%= process['busy'] %></td> <td><%= process['busy'] %></td>
<td> <td>
<div class="btn-group pull-right"> <div class="btn-group pull-right flip">
<form method="POST"> <form method="POST">
<%= csrf_tag %> <%= csrf_tag %>
<input type="hidden" name="identity" value="<%= process['identity'] %>"/> <input type="hidden" name="identity" value="<%= process['identity'] %>"/>

View file

@ -7,7 +7,7 @@
<span class="dot"></span> <span class="dot"></span>
</span> </span>
</h3> </h3>
<div class="interval-slider"> <div class="interval-slider ltr">
<span class="interval-slider-label"><%= t('PollingInterval') %>:</span> <span class="interval-slider-label"><%= t('PollingInterval') %>:</span>
<span class="current-interval">5 sec</span> <span class="current-interval">5 sec</span>
<br/> <br/>

View file

@ -1,11 +1,20 @@
<!doctype html> <!doctype html>
<html> <html dir="<%= text_direction %>">
<head> <head>
<title><%= environment_title_prefix %><%= Sidekiq::NAME %></title> <title><%= environment_title_prefix %><%= Sidekiq::NAME %></title>
<meta charset="utf8" /> <meta charset="utf8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link href="<%= root_path %>stylesheets/bootstrap.css" media="screen" rel="stylesheet" type="text/css" /> <link href="<%= root_path %>stylesheets/bootstrap.css" media="screen" rel="stylesheet" type="text/css" />
<% if rtl? %>
<link href="<%= root_path %>stylesheets/bootstrap-rtl.min.css" media="screen" rel="stylesheet" type="text/css"/>
<% end %>
<link href="<%= root_path %>stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" /> <link href="<%= root_path %>stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />
<% if rtl? %>
<link href="<%= root_path %>stylesheets/application-rtl.css" media="screen" rel="stylesheet" type="text/css" />
<% end %>
<link rel="shortcut icon" type="image/ico" href="<%= root_path %>images/favicon.ico" /> <link rel="shortcut icon" type="image/ico" href="<%= root_path %>images/favicon.ico" />
<script type="text/javascript" src="<%= root_path %>javascripts/application.js"></script> <script type="text/javascript" src="<%= root_path %>javascripts/application.js"></script>
<meta name="google" content="notranslate" /> <meta name="google" content="notranslate" />

View file

@ -55,18 +55,18 @@
<% end %> <% end %>
</table> </table>
</div> </div>
<input class="btn btn-primary btn-xs pull-left" type="submit" name="retry" value="<%= t('RetryNow') %>" /> <input class="btn btn-primary btn-xs pull-left flip" type="submit" name="retry" value="<%= t('RetryNow') %>" />
<input class="btn btn-danger btn-xs pull-left" type="submit" name="delete" value="<%= t('Delete') %>" /> <input class="btn btn-danger btn-xs pull-left flip" type="submit" name="delete" value="<%= t('Delete') %>" />
</form> </form>
<% unfiltered? do %> <% unfiltered? do %>
<form action="<%= root_path %>morgue/all/delete" method="post"> <form action="<%= root_path %>morgue/all/delete" method="post">
<%= csrf_tag %> <%= csrf_tag %>
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" /> <input class="btn btn-danger btn-xs pull-right flip" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
</form> </form>
<form action="<%= root_path %>morgue/all/retry" method="post"> <form action="<%= root_path %>morgue/all/retry" method="post">
<%= csrf_tag %> <%= csrf_tag %>
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" /> <input class="btn btn-danger btn-xs pull-right flip" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
</form> </form>
<% end %> <% end %>

View file

@ -7,7 +7,7 @@
<% end %> <% end %>
</h3> </h3>
</div> </div>
<div class="col-sm-4 pull-right"> <div class="col-sm-4 pull-right flip">
<%= erb :_paging, locals: { url: "#{root_path}queues/#{CGI.escape(@name)}" } %> <%= erb :_paging, locals: { url: "#{root_path}queues/#{CGI.escape(@name)}" } %>
</div> </div>
</header> </header>

View file

@ -55,19 +55,19 @@
<% end %> <% end %>
</table> </table>
</div> </div>
<input class="btn btn-primary btn-xs pull-left" type="submit" name="retry" value="<%= t('RetryNow') %>" /> <input class="btn btn-primary btn-xs pull-left flip" type="submit" name="retry" value="<%= t('RetryNow') %>" />
<input class="btn btn-danger btn-xs pull-left" type="submit" name="delete" value="<%= t('Delete') %>" /> <input class="btn btn-danger btn-xs pull-left flip" type="submit" name="delete" value="<%= t('Delete') %>" />
<input class="btn btn-danger btn-xs pull-left" type="submit" name="kill" value="<%= t('Kill') %>" /> <input class="btn btn-danger btn-xs pull-left flip" type="submit" name="kill" value="<%= t('Kill') %>" />
</form> </form>
<% unfiltered? do %> <% unfiltered? do %>
<form action="<%= root_path %>retries/all/delete" method="post"> <form action="<%= root_path %>retries/all/delete" method="post">
<%= csrf_tag %> <%= csrf_tag %>
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" /> <input class="btn btn-danger btn-xs pull-right flip" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
</form> </form>
<form action="<%= root_path %>retries/all/retry" method="post"> <form action="<%= root_path %>retries/all/retry" method="post">
<%= csrf_tag %> <%= csrf_tag %>
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" /> <input class="btn btn-danger btn-xs pull-right flip" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
</form> </form>
<% end %> <% end %>

View file

@ -46,8 +46,8 @@
<% end %> <% end %>
</table> </table>
</div> </div>
<input class="btn btn-danger pull-right" type="submit" name="delete" value="<%= t('Delete') %>" /> <input class="btn btn-danger pull-right flip" type="submit" name="delete" value="<%= t('Delete') %>" />
<input class="btn btn-danger pull-right" type="submit" name="add_to_queue" value="<%= t('AddToQueue') %>" /> <input class="btn btn-danger pull-right flip" type="submit" name="add_to_queue" value="<%= t('AddToQueue') %>" />
</form> </form>
<% else %> <% else %>
<div class="alert alert-success"><%= t('NoScheduledFound') %></div> <div class="alert alert-success"><%= t('NoScheduledFound') %></div>