sidekiq 7.1.4 → 8.0.9
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/Changes.md +333 -0
- data/README.md +16 -13
- data/bin/multi_queue_bench +271 -0
- data/bin/sidekiqload +31 -22
- data/bin/webload +69 -0
- data/lib/active_job/queue_adapters/sidekiq_adapter.rb +121 -0
- data/lib/generators/sidekiq/job_generator.rb +2 -0
- data/lib/generators/sidekiq/templates/job.rb.erb +1 -1
- data/lib/sidekiq/api.rb +260 -67
- data/lib/sidekiq/capsule.rb +17 -8
- data/lib/sidekiq/cli.rb +19 -20
- data/lib/sidekiq/client.rb +48 -15
- data/lib/sidekiq/component.rb +64 -3
- data/lib/sidekiq/config.rb +60 -18
- data/lib/sidekiq/deploy.rb +4 -2
- data/lib/sidekiq/embedded.rb +4 -1
- data/lib/sidekiq/fetch.rb +2 -1
- data/lib/sidekiq/iterable_job.rb +56 -0
- data/lib/sidekiq/job/interrupt_handler.rb +24 -0
- data/lib/sidekiq/job/iterable/active_record_enumerator.rb +53 -0
- data/lib/sidekiq/job/iterable/csv_enumerator.rb +47 -0
- data/lib/sidekiq/job/iterable/enumerators.rb +135 -0
- data/lib/sidekiq/job/iterable.rb +322 -0
- data/lib/sidekiq/job.rb +16 -5
- data/lib/sidekiq/job_logger.rb +15 -12
- data/lib/sidekiq/job_retry.rb +41 -13
- data/lib/sidekiq/job_util.rb +7 -1
- data/lib/sidekiq/launcher.rb +23 -11
- data/lib/sidekiq/loader.rb +57 -0
- data/lib/sidekiq/logger.rb +25 -69
- data/lib/sidekiq/manager.rb +0 -1
- data/lib/sidekiq/metrics/query.rb +76 -45
- data/lib/sidekiq/metrics/shared.rb +23 -9
- data/lib/sidekiq/metrics/tracking.rb +32 -15
- data/lib/sidekiq/middleware/current_attributes.rb +39 -14
- data/lib/sidekiq/middleware/i18n.rb +2 -0
- data/lib/sidekiq/middleware/modules.rb +2 -0
- data/lib/sidekiq/monitor.rb +6 -9
- data/lib/sidekiq/paginator.rb +16 -3
- data/lib/sidekiq/processor.rb +37 -20
- data/lib/sidekiq/profiler.rb +73 -0
- data/lib/sidekiq/rails.rb +47 -57
- data/lib/sidekiq/redis_client_adapter.rb +25 -8
- data/lib/sidekiq/redis_connection.rb +49 -9
- data/lib/sidekiq/ring_buffer.rb +3 -0
- data/lib/sidekiq/scheduled.rb +2 -2
- data/lib/sidekiq/systemd.rb +2 -0
- data/lib/sidekiq/testing.rb +34 -15
- data/lib/sidekiq/transaction_aware_client.rb +20 -5
- data/lib/sidekiq/version.rb +6 -2
- data/lib/sidekiq/web/action.rb +149 -64
- data/lib/sidekiq/web/application.rb +367 -297
- data/lib/sidekiq/web/config.rb +120 -0
- data/lib/sidekiq/web/csrf_protection.rb +8 -5
- data/lib/sidekiq/web/helpers.rb +146 -64
- data/lib/sidekiq/web/router.rb +61 -74
- data/lib/sidekiq/web.rb +53 -106
- data/lib/sidekiq.rb +11 -4
- data/sidekiq.gemspec +6 -5
- data/web/assets/images/logo.png +0 -0
- data/web/assets/images/status.png +0 -0
- data/web/assets/javascripts/application.js +66 -24
- data/web/assets/javascripts/base-charts.js +30 -16
- data/web/assets/javascripts/chartjs-adapter-date-fns.min.js +7 -0
- data/web/assets/javascripts/dashboard-charts.js +37 -11
- data/web/assets/javascripts/dashboard.js +15 -11
- data/web/assets/javascripts/metrics.js +50 -34
- data/web/assets/stylesheets/style.css +776 -0
- data/web/locales/ar.yml +2 -0
- data/web/locales/cs.yml +2 -0
- data/web/locales/da.yml +2 -0
- data/web/locales/de.yml +2 -0
- data/web/locales/el.yml +2 -0
- data/web/locales/en.yml +12 -1
- data/web/locales/es.yml +25 -2
- data/web/locales/fa.yml +2 -0
- data/web/locales/fr.yml +2 -1
- data/web/locales/gd.yml +2 -1
- data/web/locales/he.yml +2 -0
- data/web/locales/hi.yml +2 -0
- data/web/locales/it.yml +41 -1
- data/web/locales/ja.yml +2 -1
- data/web/locales/ko.yml +2 -0
- data/web/locales/lt.yml +2 -0
- data/web/locales/nb.yml +2 -0
- data/web/locales/nl.yml +2 -0
- data/web/locales/pl.yml +2 -0
- data/web/locales/{pt-br.yml → pt-BR.yml} +4 -3
- data/web/locales/pt.yml +2 -0
- data/web/locales/ru.yml +2 -0
- data/web/locales/sv.yml +2 -0
- data/web/locales/ta.yml +2 -0
- data/web/locales/tr.yml +102 -0
- data/web/locales/uk.yml +29 -4
- data/web/locales/ur.yml +2 -0
- data/web/locales/vi.yml +2 -0
- data/web/locales/{zh-cn.yml → zh-CN.yml} +86 -74
- data/web/locales/{zh-tw.yml → zh-TW.yml} +3 -2
- data/web/views/_footer.erb +31 -22
- data/web/views/_job_info.erb +91 -89
- data/web/views/_metrics_period_select.erb +13 -10
- data/web/views/_nav.erb +14 -21
- data/web/views/_paging.erb +22 -21
- data/web/views/_poll_link.erb +2 -2
- data/web/views/_summary.erb +23 -23
- data/web/views/busy.erb +123 -125
- data/web/views/dashboard.erb +71 -82
- data/web/views/dead.erb +31 -27
- data/web/views/filtering.erb +6 -0
- data/web/views/layout.erb +13 -29
- data/web/views/metrics.erb +70 -68
- data/web/views/metrics_for_job.erb +30 -40
- data/web/views/morgue.erb +65 -70
- data/web/views/profiles.erb +43 -0
- data/web/views/queue.erb +54 -52
- data/web/views/queues.erb +43 -37
- data/web/views/retries.erb +70 -75
- data/web/views/retry.erb +32 -27
- data/web/views/scheduled.erb +63 -55
- data/web/views/scheduled_job_info.erb +3 -3
- metadata +49 -27
- data/web/assets/stylesheets/application-dark.css +0 -147
- data/web/assets/stylesheets/application-rtl.css +0 -153
- data/web/assets/stylesheets/application.css +0 -724
- data/web/assets/stylesheets/bootstrap-rtl.min.css +0 -9
- data/web/assets/stylesheets/bootstrap.css +0 -5
- data/web/views/_status.erb +0 -4
data/lib/sidekiq/web.rb
CHANGED
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "erb"
|
|
4
|
-
|
|
5
|
-
require "sidekiq"
|
|
6
|
-
require "sidekiq/api"
|
|
7
|
-
require "sidekiq/paginator"
|
|
8
|
-
require "sidekiq/web/helpers"
|
|
9
|
-
|
|
10
|
-
require "sidekiq/web/router"
|
|
11
|
-
require "sidekiq/web/action"
|
|
12
|
-
require "sidekiq/web/application"
|
|
13
|
-
require "sidekiq/web/csrf_protection"
|
|
14
|
-
|
|
15
|
-
require "rack/content_length"
|
|
4
|
+
require "securerandom"
|
|
16
5
|
require "rack/builder"
|
|
17
6
|
require "rack/static"
|
|
7
|
+
require "sidekiq"
|
|
8
|
+
require "sidekiq/api"
|
|
9
|
+
require "sidekiq/web/config"
|
|
18
10
|
|
|
19
11
|
module Sidekiq
|
|
20
12
|
class Web
|
|
@@ -31,125 +23,85 @@ module Sidekiq
|
|
|
31
23
|
"Retries" => "retries",
|
|
32
24
|
"Scheduled" => "scheduled",
|
|
33
25
|
"Dead" => "morgue",
|
|
34
|
-
"Metrics" => "metrics"
|
|
26
|
+
"Metrics" => "metrics",
|
|
27
|
+
"Profiles" => "profiles"
|
|
35
28
|
}
|
|
36
29
|
|
|
37
|
-
|
|
38
|
-
CONTENT_LANGUAGE = "Content-Language"
|
|
39
|
-
CONTENT_SECURITY_POLICY = "Content-Security-Policy"
|
|
40
|
-
LOCATION = "Location"
|
|
41
|
-
X_CASCADE = "X-Cascade"
|
|
42
|
-
else
|
|
43
|
-
CONTENT_LANGUAGE = "content-language"
|
|
44
|
-
CONTENT_SECURITY_POLICY = "content-security-policy"
|
|
45
|
-
LOCATION = "location"
|
|
46
|
-
X_CASCADE = "x-cascade"
|
|
47
|
-
end
|
|
30
|
+
@@config = Sidekiq::Web::Config.new
|
|
48
31
|
|
|
49
32
|
class << self
|
|
50
|
-
def
|
|
51
|
-
|
|
33
|
+
def configure
|
|
34
|
+
if block_given?
|
|
35
|
+
yield @@config
|
|
36
|
+
else
|
|
37
|
+
@@config
|
|
38
|
+
end
|
|
52
39
|
end
|
|
53
40
|
|
|
54
|
-
def
|
|
55
|
-
|
|
41
|
+
def app_url=(url)
|
|
42
|
+
@@config.app_url = url
|
|
56
43
|
end
|
|
57
44
|
|
|
58
|
-
def
|
|
59
|
-
@custom_tabs ||= {}
|
|
60
|
-
end
|
|
61
|
-
alias_method :tabs, :custom_tabs
|
|
45
|
+
def tabs = @@config.tabs
|
|
62
46
|
|
|
63
|
-
def
|
|
64
|
-
@custom_job_info_rows ||= []
|
|
65
|
-
end
|
|
47
|
+
def locales = @@config.locales
|
|
66
48
|
|
|
67
|
-
def
|
|
68
|
-
@locales ||= LOCALES
|
|
69
|
-
end
|
|
49
|
+
def views = @@config.views
|
|
70
50
|
|
|
71
|
-
def
|
|
72
|
-
@views ||= VIEWS
|
|
73
|
-
end
|
|
51
|
+
def custom_job_info_rows = @@config.custom_job_info_rows
|
|
74
52
|
|
|
75
|
-
def
|
|
76
|
-
|
|
53
|
+
def redis_pool
|
|
54
|
+
@pool || Sidekiq.default_configuration.redis_pool
|
|
77
55
|
end
|
|
78
56
|
|
|
79
|
-
def
|
|
80
|
-
|
|
57
|
+
def redis_pool=(pool)
|
|
58
|
+
@pool = pool
|
|
81
59
|
end
|
|
82
60
|
|
|
83
|
-
def middlewares
|
|
84
|
-
@middlewares ||= []
|
|
85
|
-
end
|
|
61
|
+
def middlewares = @@config.middlewares
|
|
86
62
|
|
|
87
|
-
def use(*args, &block)
|
|
88
|
-
middlewares << [args, block]
|
|
89
|
-
end
|
|
63
|
+
def use(*args, &block) = @@config.middlewares << [args, block]
|
|
90
64
|
|
|
91
|
-
def
|
|
92
|
-
|
|
65
|
+
def register(*args, **kw, &block)
|
|
66
|
+
Sidekiq.logger.warn { "`Sidekiq::Web.register` is deprecated, use `Sidekiq::Web.configure {|cfg| cfg.register(...) }`" }
|
|
67
|
+
@@config.register(*args, **kw, &block)
|
|
93
68
|
end
|
|
94
|
-
|
|
95
|
-
attr_accessor :app_url, :redis_pool
|
|
96
|
-
attr_writer :locales, :views
|
|
97
69
|
end
|
|
98
70
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def middlewares
|
|
109
|
-
@middlewares ||= self.class.middlewares
|
|
71
|
+
# Allow user to say
|
|
72
|
+
# run Sidekiq::Web
|
|
73
|
+
# rather than:
|
|
74
|
+
# run Sidekiq::Web.new
|
|
75
|
+
def self.call(env)
|
|
76
|
+
@inst ||= new
|
|
77
|
+
@inst.call(env)
|
|
110
78
|
end
|
|
111
79
|
|
|
112
|
-
|
|
113
|
-
|
|
80
|
+
# testing, internal use only
|
|
81
|
+
def self.reset!
|
|
82
|
+
@@config.reset!
|
|
83
|
+
@inst = nil
|
|
114
84
|
end
|
|
115
85
|
|
|
116
86
|
def call(env)
|
|
87
|
+
env[:web_config] = Sidekiq::Web.configure
|
|
88
|
+
env[:csp_nonce] = SecureRandom.hex(8)
|
|
89
|
+
env[:redis_pool] = self.class.redis_pool
|
|
117
90
|
app.call(env)
|
|
118
91
|
end
|
|
119
92
|
|
|
120
|
-
def self.call(env)
|
|
121
|
-
@app ||= new
|
|
122
|
-
@app.call(env)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
93
|
def app
|
|
126
|
-
@app ||= build
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def enable(*opts)
|
|
130
|
-
opts.each { |key| set(key, true) }
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def disable(*opts)
|
|
134
|
-
opts.each { |key| set(key, false) }
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def set(attribute, value)
|
|
138
|
-
send(:"#{attribute}=", value)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def self.register(extension)
|
|
142
|
-
extension.registered(WebApplication)
|
|
94
|
+
@app ||= build(@@config)
|
|
143
95
|
end
|
|
144
96
|
|
|
145
97
|
private
|
|
146
98
|
|
|
147
|
-
def build
|
|
148
|
-
|
|
149
|
-
m = middlewares
|
|
99
|
+
def build(cfg)
|
|
100
|
+
cfg.freeze
|
|
101
|
+
m = cfg.middlewares
|
|
150
102
|
|
|
151
103
|
rules = []
|
|
152
|
-
rules = [[:all, {
|
|
104
|
+
rules = [[:all, {"cache-control" => "private, max-age=86400"}]] unless ENV["SIDEKIQ_WEB_TESTING"]
|
|
153
105
|
|
|
154
106
|
::Rack::Builder.new do
|
|
155
107
|
use Rack::Static, urls: ["/stylesheets", "/images", "/javascripts"],
|
|
@@ -157,18 +109,13 @@ module Sidekiq
|
|
|
157
109
|
cascade: true,
|
|
158
110
|
header_rules: rules
|
|
159
111
|
m.each { |middleware, block| use(*middleware, &block) }
|
|
160
|
-
use
|
|
161
|
-
run
|
|
112
|
+
use CsrfProtection if cfg[:csrf]
|
|
113
|
+
run Sidekiq::Web::Application.new(self.class)
|
|
162
114
|
end
|
|
163
115
|
end
|
|
164
116
|
end
|
|
165
|
-
|
|
166
|
-
Sidekiq::WebApplication.helpers WebHelpers
|
|
167
|
-
Sidekiq::WebApplication.helpers Sidekiq::Paginator
|
|
168
|
-
|
|
169
|
-
Sidekiq::WebAction.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
170
|
-
def _render
|
|
171
|
-
#{ERB.new(File.read(Web::LAYOUT)).src}
|
|
172
|
-
end
|
|
173
|
-
RUBY
|
|
174
117
|
end
|
|
118
|
+
|
|
119
|
+
require "sidekiq/web/router"
|
|
120
|
+
require "sidekiq/web/action"
|
|
121
|
+
require "sidekiq/web/application"
|
data/lib/sidekiq.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "sidekiq/version"
|
|
4
|
-
fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.
|
|
4
|
+
fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 3.2.0." if RUBY_PLATFORM != "java" && Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.2.0")
|
|
5
5
|
|
|
6
6
|
begin
|
|
7
7
|
require "sidekiq-ent/version"
|
|
@@ -29,9 +29,11 @@ end
|
|
|
29
29
|
|
|
30
30
|
require "sidekiq/config"
|
|
31
31
|
require "sidekiq/logger"
|
|
32
|
+
require "sidekiq/loader"
|
|
32
33
|
require "sidekiq/client"
|
|
33
34
|
require "sidekiq/transaction_aware_client"
|
|
34
35
|
require "sidekiq/job"
|
|
36
|
+
require "sidekiq/iterable_job"
|
|
35
37
|
require "sidekiq/worker_compatibility_alias"
|
|
36
38
|
require "sidekiq/redis_client_adapter"
|
|
37
39
|
|
|
@@ -93,6 +95,10 @@ module Sidekiq
|
|
|
93
95
|
default_configuration.logger
|
|
94
96
|
end
|
|
95
97
|
|
|
98
|
+
def self.loader
|
|
99
|
+
@loader ||= Loader.new
|
|
100
|
+
end
|
|
101
|
+
|
|
96
102
|
def self.configure_server(&block)
|
|
97
103
|
(@config_blocks ||= []) << block
|
|
98
104
|
yield default_configuration if server?
|
|
@@ -101,18 +107,19 @@ module Sidekiq
|
|
|
101
107
|
def self.freeze!
|
|
102
108
|
@frozen = true
|
|
103
109
|
@config_blocks = nil
|
|
110
|
+
default_configuration.freeze!
|
|
104
111
|
end
|
|
105
112
|
|
|
106
113
|
# Creates a Sidekiq::Config instance that is more tuned for embedding
|
|
107
114
|
# within an arbitrary Ruby process. Notably it reduces concurrency by
|
|
108
115
|
# default so there is less contention for CPU time with other threads.
|
|
109
116
|
#
|
|
110
|
-
#
|
|
117
|
+
# instance = Sidekiq.configure_embed do |config|
|
|
111
118
|
# config.queues = %w[critical default low]
|
|
112
119
|
# end
|
|
113
|
-
#
|
|
120
|
+
# instance.run
|
|
114
121
|
# sleep 10
|
|
115
|
-
#
|
|
122
|
+
# instance.stop
|
|
116
123
|
#
|
|
117
124
|
# NB: it is really easy to overload a Ruby process with threads due to the GIL.
|
|
118
125
|
# I do not recommend setting concurrency higher than 2-3.
|
data/sidekiq.gemspec
CHANGED
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
|
|
|
12
12
|
gem.files = %w[sidekiq.gemspec README.md Changes.md LICENSE.txt] + `git ls-files | grep -E '^(bin|lib|web)'`.split("\n")
|
|
13
13
|
gem.name = "sidekiq"
|
|
14
14
|
gem.version = Sidekiq::VERSION
|
|
15
|
-
gem.required_ruby_version = ">= 2.
|
|
15
|
+
gem.required_ruby_version = ">= 3.2.0"
|
|
16
16
|
|
|
17
17
|
gem.metadata = {
|
|
18
18
|
"homepage_uri" => "https://sidekiq.org",
|
|
@@ -23,8 +23,9 @@ Gem::Specification.new do |gem|
|
|
|
23
23
|
"rubygems_mfa_required" => "true"
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
gem.add_dependency "redis-client", ">= 0.
|
|
27
|
-
gem.add_dependency "connection_pool", ">= 2.
|
|
28
|
-
gem.add_dependency "rack", ">=
|
|
29
|
-
gem.add_dependency "
|
|
26
|
+
gem.add_dependency "redis-client", ">= 0.23.2"
|
|
27
|
+
gem.add_dependency "connection_pool", ">= 2.5.0"
|
|
28
|
+
gem.add_dependency "rack", ">= 3.1.0"
|
|
29
|
+
gem.add_dependency "json", ">= 2.9.0"
|
|
30
|
+
gem.add_dependency "logger", ">= 1.6.2"
|
|
30
31
|
end
|
data/web/assets/images/logo.png
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -18,21 +18,15 @@ function addListeners() {
|
|
|
18
18
|
})
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
document.querySelectorAll("input[data-confirm]").forEach(node => {
|
|
22
|
-
node.addEventListener("click", event => {
|
|
23
|
-
if (!window.confirm(node.getAttribute("data-confirm"))) {
|
|
24
|
-
event.preventDefault();
|
|
25
|
-
event.stopPropagation();
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
})
|
|
29
|
-
|
|
30
21
|
document.querySelectorAll("[data-toggle]").forEach(node => {
|
|
31
22
|
node.addEventListener("click", addDataToggleListeners)
|
|
32
23
|
})
|
|
33
24
|
|
|
34
|
-
|
|
25
|
+
initializeBulkToggle();
|
|
26
|
+
addShiftClickListeners();
|
|
35
27
|
updateFuzzyTimes();
|
|
28
|
+
updateNumbers();
|
|
29
|
+
updateProgressBars();
|
|
36
30
|
setLivePollFromUrl();
|
|
37
31
|
|
|
38
32
|
var buttons = document.querySelectorAll(".live-poll");
|
|
@@ -46,6 +40,8 @@ function addListeners() {
|
|
|
46
40
|
scheduleLivePoll();
|
|
47
41
|
}
|
|
48
42
|
}
|
|
43
|
+
|
|
44
|
+
document.getElementById("locale-select").addEventListener("change", updateLocale);
|
|
49
45
|
}
|
|
50
46
|
|
|
51
47
|
function addPollingListeners(_event) {
|
|
@@ -63,13 +59,24 @@ function addPollingListeners(_event) {
|
|
|
63
59
|
|
|
64
60
|
function addDataToggleListeners(event) {
|
|
65
61
|
var source = event.target || event.srcElement;
|
|
66
|
-
var targName = source.
|
|
62
|
+
var targName = source.dataset.toggle;
|
|
67
63
|
var full = document.getElementById(targName);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
full.classList.toggle("is-open");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function toggleBulkButtons() {
|
|
68
|
+
const checkboxes = document.querySelectorAll('.select-item-checkbox, .check-all-items');
|
|
69
|
+
const anyChecked = Array.from(checkboxes).some(cb => cb.checked);
|
|
70
|
+
const buttons = document.querySelectorAll('.bulk-action-buttons');
|
|
71
|
+
buttons.forEach(btn => {
|
|
72
|
+
btn.style.display = anyChecked ? 'none' : 'block';
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function initializeBulkToggle(){
|
|
77
|
+
document.querySelectorAll('.check-all-items, .select-item-checkbox').forEach(cb => {
|
|
78
|
+
cb.addEventListener('change', toggleBulkButtons);
|
|
79
|
+
});
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
function addShiftClickListeners() {
|
|
@@ -90,7 +97,7 @@ function addShiftClickListeners() {
|
|
|
90
97
|
}
|
|
91
98
|
|
|
92
99
|
function updateFuzzyTimes() {
|
|
93
|
-
var locale = document.body.
|
|
100
|
+
var locale = document.body.dataset.locale;
|
|
94
101
|
var parts = locale.split('-');
|
|
95
102
|
if (typeof parts[1] !== 'undefined') {
|
|
96
103
|
parts[1] = parts[1].toUpperCase();
|
|
@@ -102,6 +109,20 @@ function updateFuzzyTimes() {
|
|
|
102
109
|
t.cancel();
|
|
103
110
|
}
|
|
104
111
|
|
|
112
|
+
function updateNumbers() {
|
|
113
|
+
document.querySelectorAll("[data-nwp]").forEach(node => {
|
|
114
|
+
let number = parseFloat(node.textContent);
|
|
115
|
+
let precision = parseInt(node.dataset.nwp || 0);
|
|
116
|
+
if (typeof number === "number") {
|
|
117
|
+
let formatted = number.toLocaleString(undefined, {
|
|
118
|
+
minimumFractionDigits: precision,
|
|
119
|
+
maximumFractionDigits: precision,
|
|
120
|
+
});
|
|
121
|
+
node.textContent = formatted;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
105
126
|
function setLivePollFromUrl() {
|
|
106
127
|
var url_params = new URL(window.location.href).searchParams
|
|
107
128
|
|
|
@@ -112,11 +133,11 @@ function setLivePollFromUrl() {
|
|
|
112
133
|
|
|
113
134
|
function updateLivePollButton() {
|
|
114
135
|
if (localStorage.sidekiqLivePoll == "enabled") {
|
|
115
|
-
document.querySelectorAll('.live-poll-stop').forEach(box => { box.
|
|
116
|
-
document.querySelectorAll('.live-poll-start').forEach(box => { box.
|
|
136
|
+
document.querySelectorAll('.live-poll-stop').forEach(box => { box.classList.add("active") })
|
|
137
|
+
document.querySelectorAll('.live-poll-start').forEach(box => { box.classList.remove("active") })
|
|
117
138
|
} else {
|
|
118
|
-
document.querySelectorAll('.live-poll-start').forEach(box => { box.
|
|
119
|
-
document.querySelectorAll('.live-poll-stop').forEach(box => { box.
|
|
139
|
+
document.querySelectorAll('.live-poll-start').forEach(box => { box.classList.add("active") })
|
|
140
|
+
document.querySelectorAll('.live-poll-stop').forEach(box => { box.classList.remove("active") })
|
|
120
141
|
}
|
|
121
142
|
}
|
|
122
143
|
|
|
@@ -151,12 +172,33 @@ function replacePage(text) {
|
|
|
151
172
|
var page = doc.querySelector('#page')
|
|
152
173
|
document.querySelector("#page").replaceWith(page)
|
|
153
174
|
|
|
154
|
-
var header_status = doc.querySelector('.status')
|
|
155
|
-
document.querySelector('.status').replaceWith(header_status)
|
|
156
|
-
|
|
157
175
|
addListeners();
|
|
158
176
|
}
|
|
159
177
|
|
|
160
178
|
function showError(error) {
|
|
161
179
|
console.error(error)
|
|
162
180
|
}
|
|
181
|
+
|
|
182
|
+
function updateLocale(event) {
|
|
183
|
+
event.target.form.submit();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function updateProgressBars() {
|
|
187
|
+
document.querySelectorAll('.progress-bar').forEach(bar => { bar.style.width = bar.dataset.width + "%"})
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function handleConfirmDialog (event) {
|
|
191
|
+
const target = event.target
|
|
192
|
+
|
|
193
|
+
if (target.localName !== "input") { return }
|
|
194
|
+
const confirmMessage = target.dataset.confirm
|
|
195
|
+
|
|
196
|
+
if (confirmMessage === undefined) { return }
|
|
197
|
+
|
|
198
|
+
if (!window.confirm(confirmMessage)) {
|
|
199
|
+
event.preventDefault()
|
|
200
|
+
event.stopPropagation()
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
document.addEventListener("click", handleConfirmDialog)
|
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
2
2
|
Chart.defaults.borderColor = "#333";
|
|
3
3
|
Chart.defaults.color = "#aaa";
|
|
4
|
+
// Chart.defaults.borderColor = "oklch(22% 0.01 256)";
|
|
5
|
+
// Chart.defaults.color = "oklch(65% 0.01 256)";
|
|
4
6
|
}
|
|
5
7
|
|
|
6
8
|
class Colors {
|
|
7
9
|
constructor() {
|
|
8
10
|
this.assignments = {};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
12
|
+
this.light = "65%";
|
|
13
|
+
this.chroma = "0.15";
|
|
14
|
+
} else {
|
|
15
|
+
this.light = "48%";
|
|
16
|
+
this.chroma = "0.2";
|
|
17
|
+
}
|
|
18
|
+
this.success = "oklch(" + this.light + " " + this.chroma + " 179)";
|
|
19
|
+
this.failure = "oklch(" + this.light + " " + this.chroma + " 29)";
|
|
20
|
+
this.fallback = "oklch(" + this.light + " 0.02 269)";
|
|
21
|
+
this.primary = "oklch(" + this.light + " " + this.chroma + " 269)";
|
|
13
22
|
this.available = [
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"#991b1b",
|
|
23
|
+
"oklch(" + this.light + " " + this.chroma + " 256)",
|
|
24
|
+
"oklch(" + this.light + " " + this.chroma + " 196)",
|
|
25
|
+
"oklch(" + this.light + " " + this.chroma + " 46)",
|
|
26
|
+
"oklch(" + this.light + " " + this.chroma + " 316)",
|
|
27
|
+
"oklch(" + this.light + " " + this.chroma + " 106)",
|
|
28
|
+
"oklch(" + this.light + " " + this.chroma + " 226)",
|
|
29
|
+
"oklch(" + this.light + " " + this.chroma + " 136)",
|
|
30
|
+
"oklch(" + this.light + " 0.02 269)",
|
|
31
|
+
"oklch(" + this.light + " " + this.chroma + " 286)",
|
|
32
|
+
"oklch(" + this.light + " " + this.chroma + " 16)",
|
|
25
33
|
];
|
|
26
34
|
}
|
|
27
35
|
|
|
@@ -90,12 +98,18 @@ class BaseChart {
|
|
|
90
98
|
};
|
|
91
99
|
|
|
92
100
|
if (this.options.marks) {
|
|
101
|
+
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
102
|
+
this.Borderlight = "30%";
|
|
103
|
+
} else {
|
|
104
|
+
this.Borderlight = "65%";
|
|
105
|
+
}
|
|
106
|
+
|
|
93
107
|
this.options.marks.forEach(([bucket, label], i) => {
|
|
94
108
|
chartOptions.plugins.annotation.annotations[`deploy-${i}`] = {
|
|
95
109
|
type: "line",
|
|
96
110
|
xMin: bucket,
|
|
97
111
|
xMax: bucket,
|
|
98
|
-
borderColor: "
|
|
112
|
+
borderColor: "oklch(" + this.Borderlight + " 0.01 256)",
|
|
99
113
|
borderWidth: 2,
|
|
100
114
|
};
|
|
101
115
|
});
|