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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f8d4001fa7c85be52975408343d261f87b68da263508e6a97e23d2327685121
4
- data.tar.gz: a0e978fd7ea7a0959571d9c635cbecf667d319f14e3424cbd68bf90f4f936db6
3
+ metadata.gz: d04a49b7d050c6c355d565b6fce32e27cf0682154596da6d3e3f0f041762b957
4
+ data.tar.gz: bb6b5b81369db48617a240463734bca35c9a396dc170578f457e7c6ddadaf842
5
5
  SHA512:
6
- metadata.gz: 83bfda60244fda1c62876d2ea6f8a0d61f32e558c0492fd28ac4936d32fc601969c5b676ac18b21d9533796b4e21de9f57ff509b65acb253d0b5d635f52b2249
7
- data.tar.gz: 15ec2cf69ea14409f2c852c3fc3c82ffb49dabaedaccccf93084b86d88099d328f6a2b8f03e57578acff9a2272d2782a4653dc42d46c8f76625ad287bf5ab0fb
6
+ metadata.gz: 7ef504991cfaacc4ed522e923e5305075507d44ce0f5afd46b74e16f95cdc3915d854ca3bed6ab0fbf440d7fa5ef2672f8fcb64e2eca38a7c68c355b84b46a06
7
+ data.tar.gz: 8fda83fc3182b73e19a9a2c718366afde97667763705270ae7bdd02b9fc9a2a9cc1ad17dec341a78c204d301c583b235fe302e2c0932475aca3a5d9a0e113655
data/.rubocop.yml CHANGED
@@ -44,6 +44,9 @@ Style/Documentation:
44
44
  Style/FrozenStringLiteralComment:
45
45
  Enabled: false
46
46
 
47
+ Style/RescueStandardError:
48
+ Enabled: false
49
+
47
50
  Style/GlobalVars:
48
51
  Exclude:
49
52
  - spec/**/*
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
- redis_history = Sidekiq.redis { |conn| conn.lrange(history_key, 0, -1) }&.map do |raw|
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
- entry["enqueued_at"] = Time.at(entry["enqueued_at"]) if entry["enqueued_at"]
33
- entry["executed_at"] = Time.at(entry["executed_at"]) if entry["executed_at"]
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.to_i}
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
- time = Time.now
56
- store_time(time, "last_execution_at")
57
- store_execution_time_in_history(jid, time)
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.to_i) }
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.to_i)
82
+ [nil, ""].include?(timestamp) ? nil : Time.at(timestamp.to_f)
70
83
  end
71
84
 
72
- def store_execution_time_in_history(jid, time)
85
+ def update_history_entry(jid)
73
86
  Sidekiq.redis do |conn|
74
- conn.lrange(history_key, 0, -1).each_with_index do |raw, index|
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
- conn.lset(history_key, index, Sidekiq.dump_json(entry.merge("executed_at" => time.to_i)))
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
@@ -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, :last_execution_at, :history
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
- strategy.execute_task(name, params)
32
+ storage.store_execution(jid, "executed_at")
33
33
 
34
- storage.store_execution(jid)
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sidekiq
4
4
  module Tasks
5
- VERSION = "0.1.4"
5
+ VERSION = "0.1.5"
6
6
  end
7
7
  end
@@ -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
+ }
@@ -4,4 +4,5 @@
4
4
  @import url("components/tables.css");
5
5
  @import url("components/buttons.css");
6
6
  @import url("components/pagination.css");
7
-
7
+ @import url("components/status_badges.css");
8
+ @import url("components/tooltips.css");
@@ -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: "Exécuté"
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
- <% if task.history.empty? %>
39
- <p><%= t("no_history") %></p>
40
- <% else %>
41
- <table class="st-table">
42
- <thead>
43
- <tr>
44
- <th><%= t("jid") %></th>
45
- <th><%= t("args") %></th>
46
- <th><%= t("enqueued") %></th>
47
- <th><%= t("executed") %></th>
48
- </tr>
49
- </thead>
50
- <tbody>
51
- <% task.history.each do |jid_history| %>
52
- <tr>
53
- <td><%= jid_history["jid"] %></td>
54
- <td><%= jid_history["args"] %></td>
55
- <td><%= jid_history["enqueued_at"] ? relative_time(jid_history["enqueued_at"]) : "-" %></td>
56
- <td><%= jid_history["executed_at"] ? relative_time(jid_history["executed_at"]) : "-" %></td>
57
- </tr>
58
- <% end %>
59
- </tbody>
60
- </table>
61
- <% end %>
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
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-03-23 00:00:00.000000000 Z
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.5.22
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: []