sidekiq-tasks 0.1.4 → 0.1.5
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/.rubocop.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/docs/task.png +0 -0
- data/lib/sidekiq/tasks/storage.rb +36 -20
- data/lib/sidekiq/tasks/task.rb +11 -3
- data/lib/sidekiq/tasks/version.rb +1 -1
- data/lib/sidekiq/tasks/web/extension.rb +2 -0
- data/lib/sidekiq/tasks/web/helpers/pagination_helper.rb +1 -12
- data/lib/sidekiq/tasks/web/helpers/tag_helper.rb +24 -0
- data/lib/sidekiq/tasks/web/helpers/task_helper.rb +26 -0
- data/web/assets/tasks/css/components/status_badges.css +72 -0
- data/web/assets/tasks/css/components/tables.css +19 -0
- data/web/assets/tasks/css/components/tooltips.css +42 -0
- data/web/assets/tasks/css/ext.css +2 -1
- data/web/assets/tasks/js/tooltips_manager.js +51 -0
- data/web/locales/en.yml +6 -0
- data/web/locales/fr.yml +7 -1
- data/web/views/task.erb +48 -25
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d04a49b7d050c6c355d565b6fce32e27cf0682154596da6d3e3f0f041762b957
|
4
|
+
data.tar.gz: bb6b5b81369db48617a240463734bca35c9a396dc170578f457e7c6ddadaf842
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ef504991cfaacc4ed522e923e5305075507d44ce0f5afd46b74e16f95cdc3915d854ca3bed6ab0fbf440d7fa5ef2672f8fcb64e2eca38a7c68c355b84b46a06
|
7
|
+
data.tar.gz: 8fda83fc3182b73e19a9a2c718366afde97667763705270ae7bdd02b9fc9a2a9cc1ad17dec341a78c204d301c583b235fe302e2c0932475aca3a5d9a0e113655
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
## Changelog
|
2
2
|
|
3
|
+
### [0.1.5] - 2025-05-04
|
4
|
+
|
5
|
+
- Add duration, status and error reports to history.
|
6
|
+
- Fix Code Climate report by updating CI runner from `ubuntu-20.04` to `ubuntu-22.04`.
|
7
|
+
|
3
8
|
### [0.1.4] - 2025-03-23
|
4
9
|
|
5
10
|
- Fix gem load error by moving the entrypoint to the correct path.
|
data/docs/task.png
CHANGED
Binary file
|
@@ -3,6 +3,7 @@ module Sidekiq
|
|
3
3
|
class Storage
|
4
4
|
JID_PREFIX = "task".freeze
|
5
5
|
HISTORY_LIMIT = 10
|
6
|
+
ERROR_MESSAGE_MAX_LENGTH = 255
|
6
7
|
|
7
8
|
attr_reader :task_name
|
8
9
|
|
@@ -22,60 +23,75 @@ module Sidekiq
|
|
22
23
|
stored_time("last_enqueue_at")
|
23
24
|
end
|
24
25
|
|
25
|
-
def last_execution_at
|
26
|
-
stored_time("last_execution_at")
|
27
|
-
end
|
28
|
-
|
29
26
|
def history
|
30
|
-
|
27
|
+
raw_entries = Sidekiq.redis { |conn| conn.lrange(history_key, 0, -1) }
|
28
|
+
|
29
|
+
return [] unless raw_entries
|
30
|
+
|
31
|
+
raw_entries.map do |raw|
|
31
32
|
entry = Sidekiq.load_json(raw)
|
32
|
-
|
33
|
-
|
33
|
+
%w[enqueued_at executed_at finished_at].each do |key|
|
34
|
+
entry[key] = Time.at(entry[key]) if entry[key]
|
35
|
+
end
|
34
36
|
entry
|
35
37
|
end
|
36
|
-
|
37
|
-
redis_history || []
|
38
38
|
end
|
39
39
|
|
40
40
|
def store_history(jid, task_args, time)
|
41
41
|
Sidekiq.redis do |conn|
|
42
|
-
task_trace = {jid: jid, name: task_name, args: task_args, enqueued_at: time.
|
42
|
+
task_trace = {jid: jid, name: task_name, args: task_args, enqueued_at: time.to_f}
|
43
43
|
conn.lpush(history_key, Sidekiq.dump_json(task_trace))
|
44
44
|
conn.ltrim(history_key, 0, HISTORY_LIMIT - 1)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
def store_enqueue(jid, args)
|
49
|
-
time = Time.now
|
49
|
+
time = Time.now.to_f
|
50
50
|
store_time(time, "last_enqueue_at")
|
51
51
|
store_history(jid, args, time)
|
52
52
|
end
|
53
53
|
|
54
|
-
def store_execution(jid)
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
def store_execution(jid, time_key)
|
55
|
+
update_history_entry(jid) do |entry|
|
56
|
+
entry.merge(time_key => Time.now.to_f)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def store_execution_error(jid, error)
|
61
|
+
update_history_entry(jid) do |entry|
|
62
|
+
error_message = truncate_message("#{error.class}: #{error.message}", ERROR_MESSAGE_MAX_LENGTH)
|
63
|
+
entry.merge("error" => error_message)
|
64
|
+
end
|
58
65
|
end
|
59
66
|
|
60
67
|
private
|
61
68
|
|
69
|
+
def truncate_message(message, max_length)
|
70
|
+
return message if message.length <= max_length
|
71
|
+
|
72
|
+
"#{message[0...(max_length - 3)]}..."
|
73
|
+
end
|
74
|
+
|
62
75
|
def store_time(time, time_key)
|
63
|
-
Sidekiq.redis { |conn| conn.hset(jid_key, time_key, time.
|
76
|
+
Sidekiq.redis { |conn| conn.hset(jid_key, time_key, time.to_f) }
|
64
77
|
end
|
65
78
|
|
66
79
|
def stored_time(time_key)
|
67
80
|
timestamp = Sidekiq.redis { |conn| conn.hget(jid_key, time_key) }
|
68
81
|
|
69
|
-
[nil, ""].include?(timestamp) ? nil : Time.at(timestamp.
|
82
|
+
[nil, ""].include?(timestamp) ? nil : Time.at(timestamp.to_f)
|
70
83
|
end
|
71
84
|
|
72
|
-
def
|
85
|
+
def update_history_entry(jid)
|
73
86
|
Sidekiq.redis do |conn|
|
74
|
-
conn.lrange(history_key, 0, -1)
|
87
|
+
entries = conn.lrange(history_key, 0, -1)
|
88
|
+
|
89
|
+
entries.each_with_index do |raw, index|
|
75
90
|
entry = Sidekiq.load_json(raw)
|
76
91
|
next unless entry["jid"] == jid
|
77
92
|
|
78
|
-
|
93
|
+
updated_entry = yield(entry)
|
94
|
+
conn.lset(history_key, index, Sidekiq.dump_json(updated_entry))
|
79
95
|
break
|
80
96
|
end
|
81
97
|
end
|
data/lib/sidekiq/tasks/task.rb
CHANGED
@@ -7,7 +7,7 @@ module Sidekiq
|
|
7
7
|
include Sidekiq::Tasks::Validations
|
8
8
|
|
9
9
|
def_delegators :metadata, :name, :desc, :file, :args
|
10
|
-
def_delegators :storage, :last_enqueue_at, :
|
10
|
+
def_delegators :storage, :last_enqueue_at, :history
|
11
11
|
|
12
12
|
attr_reader :metadata, :strategy
|
13
13
|
|
@@ -29,9 +29,17 @@ module Sidekiq
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def execute(params = {}, jid: nil)
|
32
|
-
|
32
|
+
storage.store_execution(jid, "executed_at")
|
33
33
|
|
34
|
-
|
34
|
+
begin
|
35
|
+
strategy.execute_task(name, params)
|
36
|
+
rescue => e
|
37
|
+
storage.store_execution(jid, "finished_at")
|
38
|
+
storage.store_execution_error(jid, e)
|
39
|
+
raise
|
40
|
+
end
|
41
|
+
|
42
|
+
storage.store_execution(jid, "finished_at")
|
35
43
|
end
|
36
44
|
|
37
45
|
def storage
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "sidekiq/tasks/web/helpers/application_helper"
|
2
|
+
require "sidekiq/tasks/web/helpers/tag_helper"
|
2
3
|
require "sidekiq/tasks/web/helpers/task_helper"
|
3
4
|
require "sidekiq/tasks/web/helpers/pagination_helper"
|
4
5
|
require "sidekiq/tasks/web/search"
|
@@ -11,6 +12,7 @@ module Sidekiq
|
|
11
12
|
class Extension
|
12
13
|
def self.registered(app)
|
13
14
|
app.helpers(Sidekiq::Tasks::Web::Helpers::ApplicationHelper)
|
15
|
+
app.helpers(Sidekiq::Tasks::Web::Helpers::TagHelper)
|
14
16
|
app.helpers(Sidekiq::Tasks::Web::Helpers::TaskHelper)
|
15
17
|
app.helpers(Sidekiq::Tasks::Web::Helpers::PaginationHelper)
|
16
18
|
|
@@ -4,6 +4,7 @@ module Sidekiq
|
|
4
4
|
module Helpers
|
5
5
|
module PaginationHelper
|
6
6
|
extend self
|
7
|
+
include Sidekiq::Tasks::Web::Helpers::TagHelper
|
7
8
|
|
8
9
|
def pagination_link(root_path, link, search)
|
9
10
|
build_tag(:li, class: "st-page-item") do
|
@@ -18,18 +19,6 @@ module Sidekiq
|
|
18
19
|
|
19
20
|
private
|
20
21
|
|
21
|
-
def build_tag(tag, content = nil, **attributes, &block)
|
22
|
-
attr_string = attributes.map { |key, value| "#{key}=\"#{value}\"" }.join(" ")
|
23
|
-
|
24
|
-
"<#{tag} #{attr_string}>#{block&.call || content}</#{tag}>"
|
25
|
-
end
|
26
|
-
|
27
|
-
def build_classes(*classes, **conditions)
|
28
|
-
condition_classes = conditions.select { |_, value| value }.keys
|
29
|
-
|
30
|
-
(classes + condition_classes).join(" ")
|
31
|
-
end
|
32
|
-
|
33
22
|
def pagination_url(root_path, search, page)
|
34
23
|
"#{root_path}tasks?filter=#{ERB::Util.url_encode(search.filter)}&count=#{search.count}&page=#{page}"
|
35
24
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Tasks
|
3
|
+
module Web
|
4
|
+
module Helpers
|
5
|
+
module TagHelper
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def build_tag(tag, content = nil, **attributes, &block)
|
9
|
+
attr_string = attributes.map { |key, value| "#{key}=\"#{value}\"" }.join(" ")
|
10
|
+
attr_string = " #{attr_string}" unless attr_string.empty?
|
11
|
+
|
12
|
+
"<#{tag}#{attr_string}>#{block&.call || content}</#{tag}>"
|
13
|
+
end
|
14
|
+
|
15
|
+
def build_classes(*classes, **conditions)
|
16
|
+
condition_classes = conditions.select { |_, value| value }.keys
|
17
|
+
|
18
|
+
(classes + condition_classes).join(" ")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -4,6 +4,7 @@ module Sidekiq
|
|
4
4
|
module Helpers
|
5
5
|
module TaskHelper
|
6
6
|
extend self
|
7
|
+
include Sidekiq::Tasks::Web::Helpers::TagHelper
|
7
8
|
|
8
9
|
def parameterize_task_name(task_name)
|
9
10
|
task_name.gsub(":", "-")
|
@@ -22,6 +23,31 @@ module Sidekiq
|
|
22
23
|
def task_url(root_path, task)
|
23
24
|
"#{root_path}tasks/#{parameterize_task_name(task.name)}"
|
24
25
|
end
|
26
|
+
|
27
|
+
def task_status(jid_history)
|
28
|
+
if jid_history["error"]
|
29
|
+
:failure
|
30
|
+
elsif jid_history["finished_at"]
|
31
|
+
:success
|
32
|
+
elsif jid_history["executed_at"]
|
33
|
+
:running
|
34
|
+
else
|
35
|
+
:pending
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def format_task_duration(start_time, end_time)
|
40
|
+
return "-" unless start_time && end_time
|
41
|
+
|
42
|
+
duration_in_milliseconds = ((end_time - start_time) * 1000).to_i
|
43
|
+
|
44
|
+
if duration_in_milliseconds >= 1000
|
45
|
+
duration_in_seconds = (duration_in_milliseconds / 1000.0).round
|
46
|
+
"#{[duration_in_seconds, 1].max}s"
|
47
|
+
else
|
48
|
+
"#{[duration_in_milliseconds, 1].max}ms"
|
49
|
+
end
|
50
|
+
end
|
25
51
|
end
|
26
52
|
end
|
27
53
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
:root {
|
2
|
+
--badge-success-text: #22713d;
|
3
|
+
--badge-success-bg: #dff5e3;
|
4
|
+
--badge-success-border: #b5e2c4;
|
5
|
+
|
6
|
+
--badge-failure-text: #a82a34;
|
7
|
+
--badge-failure-bg: #fbe3e5;
|
8
|
+
--badge-failure-border: #f5b7bc;
|
9
|
+
|
10
|
+
--badge-running-text: #0b5394;
|
11
|
+
--badge-running-bg: #dceeff;
|
12
|
+
--badge-running-border: #a9d4f2;
|
13
|
+
|
14
|
+
--badge-pending-text: #8a6d1d;
|
15
|
+
--badge-pending-bg: #fff8dc;
|
16
|
+
--badge-pending-border: #f5e6ab;
|
17
|
+
}
|
18
|
+
|
19
|
+
@media (prefers-color-scheme: dark) {
|
20
|
+
:root {
|
21
|
+
--badge-success-text: #b5e2c4;
|
22
|
+
--badge-success-bg: #1a3b28;
|
23
|
+
--badge-success-border: #2f5b3f;
|
24
|
+
|
25
|
+
--badge-failure-text: #f5b7bc;
|
26
|
+
--badge-failure-bg: #3e1b1d;
|
27
|
+
--badge-failure-border: #7a2e35;
|
28
|
+
|
29
|
+
--badge-running-text: #a9d4f2;
|
30
|
+
--badge-running-bg: #1a2c3e;
|
31
|
+
--badge-running-border: #345c7f;
|
32
|
+
|
33
|
+
--badge-pending-text: #f5e6ab;
|
34
|
+
--badge-pending-bg: #3e351a;
|
35
|
+
--badge-pending-border: #7a6a2e;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
.st-status-badge {
|
40
|
+
display: inline-block;
|
41
|
+
padding: 3px 10px;
|
42
|
+
border-radius: 999px;
|
43
|
+
font-size: 11px;
|
44
|
+
font-weight: 500;
|
45
|
+
cursor: default;
|
46
|
+
border: 1px solid transparent;
|
47
|
+
white-space: nowrap;
|
48
|
+
}
|
49
|
+
|
50
|
+
.st-status-badge.success {
|
51
|
+
color: var(--badge-success-text);
|
52
|
+
background-color: var(--badge-success-bg);
|
53
|
+
border-color: var(--badge-success-border);
|
54
|
+
}
|
55
|
+
|
56
|
+
.st-status-badge.failure {
|
57
|
+
color: var(--badge-failure-text);
|
58
|
+
background-color: var(--badge-failure-bg);
|
59
|
+
border-color: var(--badge-failure-border);
|
60
|
+
}
|
61
|
+
|
62
|
+
.st-status-badge.running {
|
63
|
+
color: var(--badge-running-text);
|
64
|
+
background-color: var(--badge-running-bg);
|
65
|
+
border-color: var(--badge-running-border);
|
66
|
+
}
|
67
|
+
|
68
|
+
.st-status-badge.pending {
|
69
|
+
color: var(--badge-pending-text);
|
70
|
+
background-color: var(--badge-pending-bg);
|
71
|
+
border-color: var(--badge-pending-border);
|
72
|
+
}
|
@@ -5,6 +5,8 @@
|
|
5
5
|
--st-table-odd-bg: #fcfcfc;
|
6
6
|
--st-table-even-bg: transparent;
|
7
7
|
--st-table-header-bg: transparent;
|
8
|
+
--st-table-code-bg: #fcfcfc;
|
9
|
+
--st-table-code-text: #6c6869;
|
8
10
|
}
|
9
11
|
|
10
12
|
@media (prefers-color-scheme: dark) {
|
@@ -18,6 +20,10 @@
|
|
18
20
|
}
|
19
21
|
}
|
20
22
|
|
23
|
+
.st-table-container {
|
24
|
+
overflow: auto;
|
25
|
+
}
|
26
|
+
|
21
27
|
.st-table {
|
22
28
|
background-color: var(--st-table-bg);
|
23
29
|
color: var(--st-table-text);
|
@@ -29,8 +35,13 @@
|
|
29
35
|
.st-table thead > tr > th,
|
30
36
|
.st-table tbody > tr > th,
|
31
37
|
.st-table tbody > tr > td {
|
38
|
+
max-width: 300px;
|
39
|
+
overflow: scroll;
|
40
|
+
display: table-cell;
|
41
|
+
vertical-align: middle;
|
32
42
|
border: 1px solid var(--st-table-border);
|
33
43
|
padding: 7px 10px;
|
44
|
+
white-space: nowrap;
|
34
45
|
}
|
35
46
|
|
36
47
|
.st-table tbody tr:nth-child(odd) {
|
@@ -46,3 +57,11 @@
|
|
46
57
|
background-color: var(--st-table-header-bg);
|
47
58
|
}
|
48
59
|
|
60
|
+
.st-table code {
|
61
|
+
background-color: var(--st-table-code-bg);
|
62
|
+
color: var(--st-table-code-text);
|
63
|
+
box-shadow: 0 0 0 1px var(--st-table-border);
|
64
|
+
border-radius: 2px;
|
65
|
+
padding: 0.2em 0.4em;
|
66
|
+
border-radius: 0.2em;
|
67
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
:root {
|
2
|
+
--st-tooltip-bg: #333;
|
3
|
+
--st-tooltip-text: #fff;
|
4
|
+
--st-tooltip-shadow: rgba(0, 0, 0, 0.2);
|
5
|
+
--st-tooltip-arrow: #333;
|
6
|
+
}
|
7
|
+
|
8
|
+
@media (prefers-color-scheme: dark) {
|
9
|
+
:root {
|
10
|
+
--st-tooltip-bg: #eee;
|
11
|
+
--st-tooltip-text: #111;
|
12
|
+
--st-tooltip-shadow: rgba(255, 255, 255, 0.1);
|
13
|
+
--st-tooltip-arrow: #eee;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
.st-tooltip {
|
18
|
+
position: absolute;
|
19
|
+
background-color: var(--st-tooltip-bg);
|
20
|
+
color: var(--st-tooltip-text);
|
21
|
+
padding: 6px 10px;
|
22
|
+
border-radius: 4px;
|
23
|
+
font-size: 11px;
|
24
|
+
white-space: pre-wrap;
|
25
|
+
max-width: 300px;
|
26
|
+
z-index: 10000;
|
27
|
+
box-shadow: 0 0 10px var(--st-tooltip-shadow);
|
28
|
+
opacity: 0;
|
29
|
+
pointer-events: none;
|
30
|
+
transition: opacity 0.2s ease;
|
31
|
+
}
|
32
|
+
|
33
|
+
.st-tooltip::after {
|
34
|
+
content: "";
|
35
|
+
position: absolute;
|
36
|
+
top: 100%;
|
37
|
+
left: 50%;
|
38
|
+
transform: translateX(-50%);
|
39
|
+
border-width: 5px;
|
40
|
+
border-style: solid;
|
41
|
+
border-color: var(--st-tooltip-arrow) transparent transparent transparent;
|
42
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class TooltipsManager {
|
2
|
+
constructor(selector = '[data-tooltip]') {
|
3
|
+
this.selector = selector;
|
4
|
+
this.tooltip = null;
|
5
|
+
}
|
6
|
+
|
7
|
+
init() {
|
8
|
+
this.#createTooltipElement();
|
9
|
+
|
10
|
+
document.querySelectorAll(this.selector).forEach(element => {
|
11
|
+
element.addEventListener('mouseenter', this.#showTooltip.bind(this));
|
12
|
+
element.addEventListener('mouseleave', this.#hideTooltip.bind(this));
|
13
|
+
});
|
14
|
+
}
|
15
|
+
|
16
|
+
#createTooltipElement() {
|
17
|
+
this.tooltip = document.createElement('div');
|
18
|
+
this.tooltip.className = 'st-tooltip';
|
19
|
+
document.body.appendChild(this.tooltip);
|
20
|
+
}
|
21
|
+
|
22
|
+
#showTooltip(event) {
|
23
|
+
const target = event.currentTarget;
|
24
|
+
const text = target.getAttribute('data-tooltip');
|
25
|
+
|
26
|
+
if (!text) return;
|
27
|
+
|
28
|
+
this.tooltip.textContent = text;
|
29
|
+
this.tooltip.style.top = '0px';
|
30
|
+
this.tooltip.style.left = '-9999px';
|
31
|
+
this.tooltip.style.opacity = '1';
|
32
|
+
|
33
|
+
requestAnimationFrame(() => {
|
34
|
+
const rect = target.getBoundingClientRect();
|
35
|
+
const tooltipRect = this.tooltip.getBoundingClientRect();
|
36
|
+
const top = rect.top + window.scrollY - tooltipRect.height - 8;
|
37
|
+
const left = rect.left + window.scrollX + rect.width / 2 - tooltipRect.width / 2;
|
38
|
+
|
39
|
+
this.tooltip.style.top = `${top}px`;
|
40
|
+
this.tooltip.style.left = `${left}px`;
|
41
|
+
});
|
42
|
+
}
|
43
|
+
|
44
|
+
#hideTooltip() {
|
45
|
+
this.tooltip.style.opacity = '0';
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
document.addEventListener('DOMContentLoaded', () => {
|
50
|
+
new TooltipsManager().init();
|
51
|
+
});
|
data/web/locales/en.yml
CHANGED
@@ -13,9 +13,15 @@ en:
|
|
13
13
|
args: "Arguments"
|
14
14
|
enqueued: "Enqueued"
|
15
15
|
executed: "Executed"
|
16
|
+
duration: "Duration"
|
16
17
|
task: "Task"
|
17
18
|
desc: "Description"
|
18
19
|
strategy: "Strategy"
|
19
20
|
run_task: "Run task"
|
20
21
|
enqueue: "Enqueue"
|
21
22
|
env_confirmation: "Please enter '%{current_env}' to confirm."
|
23
|
+
pending: "Pending"
|
24
|
+
running: "Running"
|
25
|
+
success: "Success"
|
26
|
+
failure: "Failure"
|
27
|
+
task_time: "%m/%d/%y %H:%M:%S"
|
data/web/locales/fr.yml
CHANGED
@@ -12,10 +12,16 @@ fr:
|
|
12
12
|
jid: "JID"
|
13
13
|
args: "Arguments"
|
14
14
|
enqueued: "Mise en file d'attente"
|
15
|
-
executed: "
|
15
|
+
executed: "Exécutée"
|
16
|
+
duration: "Durée"
|
16
17
|
task: "Tâche"
|
17
18
|
desc: "Description"
|
18
19
|
strategy: "Stratégie"
|
19
20
|
run_task: "Exécuter la tâche"
|
20
21
|
enqueue: "Mettre en file d'attente"
|
21
22
|
env_confirmation: "Veuillez saisir '%{current_env}' pour confirmer."
|
23
|
+
pending: "En attente"
|
24
|
+
running: "En cours"
|
25
|
+
success: "Succès"
|
26
|
+
failure: "Echec"
|
27
|
+
task_time: "%d/%m/%y %H:%M:%S"
|
data/web/views/task.erb
CHANGED
@@ -35,30 +35,51 @@
|
|
35
35
|
</div>
|
36
36
|
</header>
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
<
|
43
|
-
|
44
|
-
<
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
<
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
38
|
+
<div class="st-table-container">
|
39
|
+
<% if task.history.empty? %>
|
40
|
+
<p><%= t("no_history") %></p>
|
41
|
+
<% else %>
|
42
|
+
<table class="st-table">
|
43
|
+
<thead>
|
44
|
+
<tr>
|
45
|
+
<th><%= t("jid") %></th>
|
46
|
+
<th><%= t("args") %></th>
|
47
|
+
<th><%= t("enqueued") %></th>
|
48
|
+
<th><%= t("executed") %></th>
|
49
|
+
<th><%= t("duration") %></th>
|
50
|
+
<th><%= t("status") %></th>
|
51
|
+
</tr>
|
52
|
+
</thead>
|
53
|
+
<tbody>
|
54
|
+
<% task.history.each do |jid_history| %>
|
55
|
+
<tr>
|
56
|
+
<td><%= jid_history["jid"] %></td>
|
57
|
+
<td>
|
58
|
+
<code><%= jid_history["args"] %></code>
|
59
|
+
</td>
|
60
|
+
<td>
|
61
|
+
<%= jid_history["enqueued_at"] ? jid_history["enqueued_at"].strftime(t("task_time")) : "-" %>
|
62
|
+
</td>
|
63
|
+
<td>
|
64
|
+
<%= jid_history["executed_at"] ? jid_history["executed_at"].strftime(t("task_time")) : "-" %>
|
65
|
+
</td>
|
66
|
+
<td>
|
67
|
+
<%= format_task_duration(jid_history["enqueued_at"], jid_history["finished_at"]) %>
|
68
|
+
</td>
|
69
|
+
<td>
|
70
|
+
<%= build_tag(
|
71
|
+
:span,
|
72
|
+
t(task_status(jid_history).to_s).capitalize,
|
73
|
+
class: "st-status-badge #{task_status(jid_history)}",
|
74
|
+
"data-tooltip": jid_history["error"],
|
75
|
+
) %>
|
76
|
+
</td>
|
77
|
+
</tr>
|
78
|
+
<% end %>
|
79
|
+
</tbody>
|
80
|
+
</table>
|
81
|
+
<% end %>
|
82
|
+
</div>
|
62
83
|
|
63
84
|
<header class="">
|
64
85
|
<div class="">
|
@@ -85,13 +106,15 @@
|
|
85
106
|
<input type="text" id="envConfirmationInput" class="st-input" name="env_confirmation" data-current-env="<%= current_env %>" required/>
|
86
107
|
</div>
|
87
108
|
|
88
|
-
<button type="submit" class="st-button" id="submitBtn" disabled>
|
109
|
+
<button type="submit" class="st-button" id="submitBtn" disabled>
|
89
110
|
<%= t("enqueue") %>
|
90
111
|
</button>
|
91
112
|
</form>
|
92
113
|
|
93
114
|
<% if Sidekiq::Tasks::Web::SIDEKIQ_GTE_7_3_0 %>
|
94
115
|
<%= script_tag "tasks/js/env_confirmation.js" %>
|
116
|
+
<%= script_tag "tasks/js/tooltips_manager.js" %>
|
95
117
|
<% else %>
|
96
118
|
<script type="text/javascript" src="<%= root_path %>tasks/js/env_confirmation.js"></script>
|
119
|
+
<script type="text/javascript" src="<%= root_path %>tasks/js/tooltips_manager.js"></script>
|
97
120
|
<% end %>
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-
|
10
|
+
date: 2025-05-04 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rake
|
@@ -261,6 +260,7 @@ files:
|
|
261
260
|
- lib/sidekiq/tasks/web/extension.rb
|
262
261
|
- lib/sidekiq/tasks/web/helpers/application_helper.rb
|
263
262
|
- lib/sidekiq/tasks/web/helpers/pagination_helper.rb
|
263
|
+
- lib/sidekiq/tasks/web/helpers/tag_helper.rb
|
264
264
|
- lib/sidekiq/tasks/web/helpers/task_helper.rb
|
265
265
|
- lib/sidekiq/tasks/web/pagination.rb
|
266
266
|
- lib/sidekiq/tasks/web/params.rb
|
@@ -269,11 +269,14 @@ files:
|
|
269
269
|
- web/assets/tasks/css/components/buttons.css
|
270
270
|
- web/assets/tasks/css/components/forms.css
|
271
271
|
- web/assets/tasks/css/components/pagination.css
|
272
|
+
- web/assets/tasks/css/components/status_badges.css
|
272
273
|
- web/assets/tasks/css/components/tables.css
|
274
|
+
- web/assets/tasks/css/components/tooltips.css
|
273
275
|
- web/assets/tasks/css/ext.css
|
274
276
|
- web/assets/tasks/css/layouts/header.css
|
275
277
|
- web/assets/tasks/css/utilities.css
|
276
278
|
- web/assets/tasks/js/env_confirmation.js
|
279
|
+
- web/assets/tasks/js/tooltips_manager.js
|
277
280
|
- web/locales/en.yml
|
278
281
|
- web/locales/fr.yml
|
279
282
|
- web/views/_pagination.erb
|
@@ -286,7 +289,6 @@ metadata:
|
|
286
289
|
homepage_uri: https://github.com/victorauthiat/sidekiq-tasks
|
287
290
|
source_code_uri: https://github.com/victorauthiat/sidekiq-tasks/blob/master
|
288
291
|
changelog_uri: https://github.com/victorauthiat/sidekiq-tasks/blob/master/CHANGELOG.md
|
289
|
-
post_install_message:
|
290
292
|
rdoc_options: []
|
291
293
|
require_paths:
|
292
294
|
- lib
|
@@ -301,8 +303,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
301
303
|
- !ruby/object:Gem::Version
|
302
304
|
version: '0'
|
303
305
|
requirements: []
|
304
|
-
rubygems_version: 3.
|
305
|
-
signing_key:
|
306
|
+
rubygems_version: 3.6.2
|
306
307
|
specification_version: 4
|
307
308
|
summary: Sidekiq extension for launching tasks.
|
308
309
|
test_files: []
|