karafka-web 0.10.3 → 0.10.4
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +2 -2
- data/karafka-web.gemspec +1 -3
- data/lib/karafka/web/config.rb +6 -1
- data/lib/karafka/web/contracts/config.rb +1 -0
- data/lib/karafka/web/management/actions/create_topics.rb +1 -1
- data/lib/karafka/web/pro/loader.rb +19 -0
- data/lib/karafka/web/tracking/consumers/listeners/errors.rb +38 -9
- data/lib/karafka/web/tracking/producers/reporter.rb +1 -8
- data/lib/karafka/web/ui/public/javascripts/application.min.js +3 -2
- data/lib/karafka/web/ui/public/javascripts/application.min.js.br +0 -0
- data/lib/karafka/web/ui/public/javascripts/application.min.js.gz +0 -0
- data/lib/karafka/web/ui/public/javascripts/components/btn_toggle_manager.js +17 -7
- data/lib/karafka/web/ui/public/stylesheets/application.min.css +2 -1
- data/lib/karafka/web/ui/public/stylesheets/application.min.css.br +0 -0
- data/lib/karafka/web/ui/public/stylesheets/application.min.css.gz +0 -0
- data/lib/karafka/web/version.rb +1 -1
- data/lib/karafka/web.rb +6 -1
- data/package-lock.json +40 -35
- data.tar.gz.sig +0 -0
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 13c431e0fa6d1b8927bd419298bc0ea522f0e823f91197fe989f72a9a08479ad
|
|
4
|
+
data.tar.gz: 6424f804a013bc34d1393fa79962cfacab6e6d5028726b7e90e93ada457b7a48
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e3ccb77dcf9624e1ca23473a963ea59cd8efc227feae098c7a80898b45c573eb70b564fd963abc6d3b0dd01a4b9e0577c1708bc2904afa6c5523360fc3880362
|
|
7
|
+
data.tar.gz: 60f20e2ed98fb8818164157e91ce117c5fb2d6b60f5c1371abef787f0f637269f27ed378a0ca8ffe7e95c43defddfc4749cfe1c06cbf905c8e591f8b171c2c36
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Karafka Web Changelog
|
|
2
2
|
|
|
3
|
+
## 0.10.4 (2024-11-26)
|
|
4
|
+
- **[Breaking]** Drop Ruby `3.0` support according to the EOL schedule.
|
|
5
|
+
- [Enhancement] Extract producers tracking `sync_threshold` into an internal config.
|
|
6
|
+
- [Enhancement] Support complex Pro license loading strategies (Pro).
|
|
7
|
+
- [Enhancement] Change default `retention.ms` for the metrics topic to support Redpanda Cloud defaults (#450).
|
|
8
|
+
- [Enhancement] Include subscription group id in the consumers error tracking metadata.
|
|
9
|
+
- [Enhancement] Collect metadata details of low level client errors when error tracking.
|
|
10
|
+
- [Enhancement] Collect metadata details of low level listener errors when error tracking.
|
|
11
|
+
- [Fix] Toggle menu button post-turbo refresh stops working.
|
|
12
|
+
|
|
3
13
|
## 0.10.3 (2024-09-17)
|
|
4
14
|
- **[Feature]** Introduce ability to brand Web UI with environment (Pro).
|
|
5
15
|
- [Enhancement] Provide assignment status in the routing (Pro).
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
karafka-web (0.10.
|
|
4
|
+
karafka-web (0.10.4)
|
|
5
5
|
erubi (~> 1.4)
|
|
6
6
|
karafka (>= 2.4.10, < 2.5.0)
|
|
7
7
|
karafka-core (>= 2.4.0, < 2.5.0)
|
|
@@ -56,7 +56,7 @@ GEM
|
|
|
56
56
|
logger (1.6.1)
|
|
57
57
|
mini_portile2 (2.8.7)
|
|
58
58
|
minitest (5.25.1)
|
|
59
|
-
ostruct (0.6.
|
|
59
|
+
ostruct (0.6.1)
|
|
60
60
|
raabro (1.4.0)
|
|
61
61
|
rack (3.1.4)
|
|
62
62
|
rack-test (2.1.0)
|
data/karafka-web.gemspec
CHANGED
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
|
|
25
25
|
spec.add_development_dependency 'rackup', '~> 0.2'
|
|
26
26
|
|
|
27
|
-
spec.required_ruby_version = '>= 3.
|
|
27
|
+
spec.required_ruby_version = '>= 3.1.0'
|
|
28
28
|
|
|
29
29
|
if $PROGRAM_NAME.end_with?('gem')
|
|
30
30
|
spec.signing_key = File.expand_path('~/.ssh/gem-private_key.pem')
|
|
@@ -41,8 +41,6 @@ Gem::Specification.new do |spec|
|
|
|
41
41
|
.reject { |f| f.start_with?('.') }
|
|
42
42
|
.reject { |f| f.end_with?('.map') }
|
|
43
43
|
|
|
44
|
-
p spec.files.select { |a| a.include?('.map')}
|
|
45
|
-
|
|
46
44
|
spec.metadata = {
|
|
47
45
|
'funding_uri' => 'https://karafka.io/#become-pro',
|
|
48
46
|
'homepage_uri' => 'https://karafka.io',
|
data/lib/karafka/web/config.rb
CHANGED
|
@@ -76,7 +76,7 @@ module Karafka
|
|
|
76
76
|
# Reports the metrics collected in the consumer sampler
|
|
77
77
|
setting :reporter, default: Tracking::Consumers::Reporter.new
|
|
78
78
|
|
|
79
|
-
# Minimum number of messages to produce
|
|
79
|
+
# Minimum number of messages to produce them in sync mode
|
|
80
80
|
# This acts as a small back-off not to overload the system in case we would have
|
|
81
81
|
# extremely big number of errors and reports happening
|
|
82
82
|
setting :sync_threshold, default: 50
|
|
@@ -98,6 +98,11 @@ module Karafka
|
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
setting :producers do
|
|
101
|
+
# Minimum number of messages to produce them in sync mode
|
|
102
|
+
# This acts as a small back-off not to overload the system in case we would have
|
|
103
|
+
# extremely big number of errors happening
|
|
104
|
+
setting :sync_threshold, default: 25
|
|
105
|
+
|
|
101
106
|
# Reports the metrics collected in the producer sampler
|
|
102
107
|
setting :reporter, default: Tracking::Producers::Reporter.new
|
|
103
108
|
|
|
@@ -17,6 +17,25 @@ module Karafka
|
|
|
17
17
|
# Loader requires and loads all the pro components only when they are needed
|
|
18
18
|
class Loader
|
|
19
19
|
class << self
|
|
20
|
+
# This loads the pro components into memory in case someone required karafka-web prior
|
|
21
|
+
# to the license usage. This can happen for users with complex require flows, where
|
|
22
|
+
# Karafka license is not part of the standard flow
|
|
23
|
+
#
|
|
24
|
+
# In such cases Web may not notice that Karafka should operate in a Pro mode when it is
|
|
25
|
+
# being required via Zeitwerk. In such cases we load Pro components prior to the setup.
|
|
26
|
+
def load_on_late_setup
|
|
27
|
+
return if defined?(Karafka::Web::Pro::Commanding)
|
|
28
|
+
|
|
29
|
+
loader = Zeitwerk::Loader.new
|
|
30
|
+
loader.push_dir(
|
|
31
|
+
File.join(Karafka::Web.gem_root, 'lib/karafka/web/pro'),
|
|
32
|
+
namespace: Karafka::Web::Pro
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
loader.setup
|
|
36
|
+
loader.eager_load
|
|
37
|
+
end
|
|
38
|
+
|
|
20
39
|
# Loads all the Web UI pro components and configures them wherever it is expected
|
|
21
40
|
# @param config [Karafka::Core::Configurable::Node] web config that we can alter with pro
|
|
22
41
|
# components
|
|
@@ -18,17 +18,24 @@ module Karafka
|
|
|
18
18
|
#
|
|
19
19
|
# @param event [Karafka::Core::Monitoring::Event]
|
|
20
20
|
def on_error_occurred(event)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
caller_ref = event[:caller]
|
|
22
|
+
|
|
23
|
+
# Collect extra info if it was a consumer related error.
|
|
24
|
+
# Those come from user code
|
|
25
|
+
details = case caller_ref
|
|
26
|
+
when Karafka::BaseConsumer
|
|
27
|
+
extract_consumer_info(caller_ref)
|
|
28
|
+
when Karafka::Connection::Client
|
|
29
|
+
extract_client_info(caller_ref)
|
|
30
|
+
when Karafka::Connection::Listener
|
|
31
|
+
extract_listener_info(caller_ref)
|
|
32
|
+
else
|
|
33
|
+
{}
|
|
34
|
+
end
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
error_class, error_message, backtrace = extract_error_info(event[:error])
|
|
31
37
|
|
|
38
|
+
track do |sampler|
|
|
32
39
|
sampler.errors << {
|
|
33
40
|
schema_version: SCHEMA_VERSION,
|
|
34
41
|
type: event[:type],
|
|
@@ -70,6 +77,7 @@ module Karafka
|
|
|
70
77
|
{
|
|
71
78
|
topic: consumer.topic.name,
|
|
72
79
|
consumer_group: consumer.topic.consumer_group.id,
|
|
80
|
+
subscription_group: consumer.topic.subscription_group.id,
|
|
73
81
|
partition: consumer.partition,
|
|
74
82
|
first_offset: consumer.messages.metadata.first_offset,
|
|
75
83
|
last_offset: consumer.messages.metadata.last_offset,
|
|
@@ -80,6 +88,27 @@ module Karafka
|
|
|
80
88
|
tags: consumer.tags
|
|
81
89
|
}
|
|
82
90
|
end
|
|
91
|
+
|
|
92
|
+
# @param client [::Karafka::Connection::Client]
|
|
93
|
+
# @return [Hash] hash with client specific info for details of error
|
|
94
|
+
def extract_client_info(client)
|
|
95
|
+
{
|
|
96
|
+
consumer_group: client.subscription_group.consumer_group.id,
|
|
97
|
+
subscription_group: client.subscription_group.id,
|
|
98
|
+
name: client.name,
|
|
99
|
+
id: client.id
|
|
100
|
+
}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @param listener [::Karafka::Connection::Listener]
|
|
104
|
+
# @return [Hash] hash with listener specific info for details of error
|
|
105
|
+
def extract_listener_info(listener)
|
|
106
|
+
{
|
|
107
|
+
consumer_group: listener.subscription_group.consumer_group.id,
|
|
108
|
+
subscription_group: listener.subscription_group.id,
|
|
109
|
+
id: listener.id
|
|
110
|
+
}
|
|
111
|
+
end
|
|
83
112
|
end
|
|
84
113
|
end
|
|
85
114
|
end
|
|
@@ -10,13 +10,6 @@ module Karafka
|
|
|
10
10
|
# because there is no expectation on immediate status updates for producers and their
|
|
11
11
|
# dispatch flow is always periodic based.
|
|
12
12
|
class Reporter < Tracking::Reporter
|
|
13
|
-
# Minimum number of messages to produce to produce them in sync mode
|
|
14
|
-
# This acts as a small back-off not to overload the system in case we would have
|
|
15
|
-
# extremely big number of errors happening
|
|
16
|
-
PRODUCE_SYNC_THRESHOLD = 25
|
|
17
|
-
|
|
18
|
-
private_constant :PRODUCE_SYNC_THRESHOLD
|
|
19
|
-
|
|
20
13
|
# This mutex is shared between tracker and samplers so there is no case where metrics
|
|
21
14
|
# would be collected same time tracker reports
|
|
22
15
|
MUTEX = Mutex.new
|
|
@@ -82,7 +75,7 @@ module Karafka
|
|
|
82
75
|
# normal operations we should not have that many messages to dispatch and it should not
|
|
83
76
|
# slowdown any processing.
|
|
84
77
|
def produce(messages)
|
|
85
|
-
if messages.count >=
|
|
78
|
+
if messages.count >= ::Karafka::Web.config.tracking.producers.sync_threshold
|
|
86
79
|
::Karafka::Web.producer.produce_many_sync(messages)
|
|
87
80
|
else
|
|
88
81
|
::Karafka::Web.producer.produce_many_async(messages)
|
|
@@ -51,7 +51,7 @@ function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"f
|
|
|
51
51
|
/*! Source: lib/karafka/web/ui/public/javascripts/charts/data_formatting_utility.js */
|
|
52
52
|
let DataFormattingUtils={niceBytes(e,t=2){let i=0,s=parseInt(e,10)||0;for(;1024<=s&&++i;)s/=1024;return s.toFixed(s<10&&0<i?1:t)+" "+["bytes","KB","MB","GB","TB","PB","EB","ZB","YB"][i]},formatLabelX(e,t){return"date"!==t?e:("00"+((t=new Date(1e3*e)).getMonth()+1)).slice(-2)+"/"+("00"+t.getDate()).slice(-2)+"/"+t.getFullYear()+" "+("00"+t.getHours()).slice(-2)+":"+("00"+t.getMinutes()).slice(-2)+":"+("00"+t.getSeconds()).slice(-2)},formatTooltip(e,t){var i=t.parsed.y,s=t.dataset.label;switch(e){case"percentage":return Math.floor(i)===i?s+": "+i+" %":s+": "+Math.round(100*i)/100+" %";case"memory":return s+": "+DataFormattingUtils.niceBytes(1024*i,2);default:return t.yLabel}},formatLabelY(e,t){switch(e){case"percentage":return Math.floor(t)===t?t+"%":Math.round(100*t)/100+"%";case"memory":return DataFormattingUtils.niceBytes(1024*t,1);default:return Math.floor(t)===t?t:Math.round(100*t)/100}},isFractionalPrecision(e){return e!==Math.floor(e)}};
|
|
53
53
|
/*! Source: lib/karafka/web/ui/public/javascripts/charts/dataset_state_manager.js */class DatasetStateManager{constructor(){this.storageKey="karafkaDisabledDatasets"}readAll(){var e=localStorage.getItem(this.storageKey);return e?JSON.parse(e):{}}saveAll(e){localStorage.setItem(this.storageKey,JSON.stringify(e))}saveCurrent(){var e=document.querySelectorAll(".chartjs"),t=window.location.href.split("?")[0];let i={};var s=this.readAll();e.forEach(e=>{var e=e.id,t=Chart.getChart(e);t&&t.legend&&t.legend.legendItems&&0<(t=t.legend.legendItems.map((e,t)=>e.hidden?t:null).filter(e=>null!==e)).length&&(i[e]=t)}),s[t]=i,this.saveAll(s)}getCurrentChart(e){var t=window.location.href.split("?")[0];return(this.readAll()[t]||{})[e]||[]}}
|
|
54
|
-
/*! Source: lib/karafka/web/ui/public/javascripts/components/btn_toggle_manager.js */class BtnToggleManager{constructor(e=".btn-toggle",t="hidden"){this.btnClass=e,this.visibilityClass=t,this.init()}init(){document.querySelectorAll(this.btnClass).forEach(t=>{let i=t.getAttribute("data-toggle-target"),s=document.getElementById(i);s&&(this.restoreVisibility(t,s),t.addEventListener("click",()=>{var e=!s.classList.contains(this.visibilityClass);s.classList.toggle(this.visibilityClass),t.classList.toggle("active",!e),this.saveVisibility(i,!e)}))})}saveVisibility(e,t){localStorage.setItem(e+"_visibility",t)}restoreVisibility(e,t){var i=localStorage.getItem(t.id+"_visibility"),i=i?"true"===i:!t.classList.contains(this.visibilityClass);t.classList.toggle(this.visibilityClass,!i),e.classList.toggle("active",i)}}
|
|
54
|
+
/*! Source: lib/karafka/web/ui/public/javascripts/components/btn_toggle_manager.js */class BtnToggleManager{constructor(e=".btn-toggle",t="hidden"){this.btnClass=e,this.visibilityClass=t,this.init()}init(){document.querySelectorAll(this.btnClass).forEach(t=>{let i=t.getAttribute("data-toggle-target"),s=document.getElementById(i);s&&(this.restoreVisibility(t,s),t._isClickListenerAdded||(t.addEventListener("click",()=>{var e=!s.classList.contains(this.visibilityClass);s.classList.toggle(this.visibilityClass),t.classList.toggle("active",!e),this.saveVisibility(i,!e)}),t._isClickListenerAdded=!0))})}saveVisibility(e,t){localStorage.setItem(e+"_visibility",t)}restoreVisibility(e,t){var i=localStorage.getItem(t.id+"_visibility"),i=i?"true"===i:!t.classList.contains(this.visibilityClass);t.classList.toggle(this.visibilityClass,!i),e.classList.toggle("active",i)}}
|
|
55
55
|
/*! Source: lib/karafka/web/ui/public/javascripts/components/charts.js */function refreshCharts(e){(new LineChartsManager).refreshAndRender(e,!0),(new BarChartManager).refreshAndRenderBarCharts(e,!0)}function manageCharts(){(new LineChartsManager).refreshAndRender(document,!1),(new BarChartManager).refreshAndRenderBarCharts(document,!1)}
|
|
56
56
|
/*! Source: lib/karafka/web/ui/public/javascripts/components/live_poll.js */var livePollTimer=null,oldDOM=null,datePicker=null,startURL=window.location.href;let isHoveringOverClickable=!1;function initLivePolling(){document.addEventListener("mouseover",function(e){isElementClickable(e.target)&&(isHoveringOverClickable=!0)}),document.addEventListener("mouseout",function(e){isElementClickable(e.target)&&(isHoveringOverClickable=!1)}),null==localStorage.karafkaLivePoll&&(localStorage.karafkaLivePoll="enabled")}function isFormActive(){var e=document.activeElement;return["INPUT","TEXTAREA","SELECT","BUTTON","FIELDSET"].includes(e.tagName)}function isElementClickable(e){return!!("A"===e.tagName||"BUTTON"===e.tagName||"INPUT"===e.tagName&&("button"===e.type||"submit"===e.type)||e.hasAttribute("onclick")||"function"==typeof e.onclick||"SPAN"===e.tagName&&e.closest(".tab-container")||e.closest("button")||e.closest("a"))}function isUserHoveringOverClickable(){return isHoveringOverClickable}function isAnyTextSelected(){var e="";return void 0!==window.getSelection?e=window.getSelection().toString():void 0!==document.selection&&"Text"==document.selection.type&&(e=document.selection.createRange().text),""!=e}function isCollapsingHappening(){return 0<document.querySelectorAll(".collapsing").length}function isPollingPossible(e=!1){return!(isFormActive()||isUserHoveringOverClickable()||isAnyTextSelected()||isOffsetLookupCalendarVisible()||isAnyModalOpen()||isCollapsingHappening()||isTurboOperating()||e&&startURL!=window.location.href)}function isAnyModalOpen(){var e;for(e of document.querySelectorAll("dialog"))if(e.open)return!0;return!1}function bindPollingButtonClick(){var e=document.getElementById("live-poll");null!=e&&e.addEventListener("click",handleLivePollingButtonClick)}function handleLivePollingButtonClick(){toggleLivePollState(),setLivePollButton(),setPollingListener()}function toggleLivePollState(){"enabled"==localStorage.karafkaLivePoll?localStorage.karafkaLivePoll="disabled":localStorage.karafkaLivePoll="enabled"}function setLivePollButton(){null!=(selector=document.getElementById("live-poll"))&&("enabled"==localStorage.karafkaLivePoll?(selector.classList.add("text-base-content"),selector.classList.remove("text-gray-500")):(selector.classList.add("text-gray-500"),selector.classList.remove("text-base-content")))}function checkResponse(e){if(e.ok)return e;throw e}function refreshPage(e){if(!isPollingPossible())return!1;var t,e=(new DOMParser).parseFromString(e,"text/html"),i=e.getElementById("content");oldDOM!=i.innerHTML&&(t=document.querySelectorAll(".chartjs").length,0==i.querySelectorAll(".chartjs").length||0==t?(document.getElementById("content").replaceWith(i),addListeners()):(t=e.getElementById("refreshable"),document.getElementById("refreshable").replaceWith(t),refreshCharts(e)),oldDOM=i.innerHTML)}function showError(e){console.error(e)}function scheduleLivePoll(){null==oldDOM&&(oldDOM=document.getElementById("content").innerHTML);let e=parseInt(localStorage.karafkaTimeInterval)||5e3;e<1e3&&(localStorage.karafkaTimeInterval=5e3,e=5e3),livePollTimer=setTimeout(livePollCallback,e)}function livePollCallback(){clearTimeout(livePollTimer),livePollTimer=null,isPollingPossible(!1)?(startURL=window.location.href,fetch(window.location.href).then(checkResponse).then(e=>e.text()).then(refreshPage).catch(showError).finally(setPollingListener)):setPollingListener()}function setPollingListener(){var e=document.getElementById("live-poll"),t=localStorage.karafkaLivePoll;"disabled"==t||null==t||null==e?(clearTimeout(livePollTimer),livePollTimer=null):(clearTimeout(livePollTimer),scheduleLivePoll())}
|
|
57
57
|
/*! Source: lib/karafka/web/ui/public/javascripts/components/offset_datetime.js */function loadOffsetLookupDatePicker(){var e={locale:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",clear:"Clear",dateFormat:"yyyy-MM-dd",timeFormat:"HH:mm",firstDay:1},timepicker:!0,onSelect:({})=>{document.getElementById("offset-lookup-datepicker").value=""},onShow:function(){offsetLookupDatePicker.selectDate((new Date).getTime()),offsetLookupDatePicker.maxDate=new Date},onHide:function(){offsetLookupDatePicker.selectDate((new Date).getTime())},buttons:[{content(e){return"Go to offset"},onClick(e){var t=e.selectedDates[0]||new Date,i=e.$el.dataset.target;e.hide(),location.href=i+"/"+formatRedirectDateTime(t)}}]};null!=offsetLookupDatePicker&&offsetLookupDatePicker.destroy(),null!=document.getElementById("offset-lookup-datepicker")&&((offsetLookupDatePicker=new AirDatepicker("#offset-lookup-datepicker",e)).maxDate=new Date,offsetLookupDatePicker.selectDate((new Date).getTime()))}function formatRedirectDateTime(e){return e.getFullYear()+`-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}/${String(e.getHours()).padStart(2,"0")}:`+String(e.getMinutes()).padStart(2,"0")}function isOffsetLookupCalendarVisible(){return null!=offsetLookupDatePicker&&offsetLookupDatePicker.visible}
|
|
@@ -61,4 +61,5 @@ let DataFormattingUtils={niceBytes(e,t=2){let i=0,s=parseInt(e,10)||0;for(;1024<
|
|
|
61
61
|
/*! Source: lib/karafka/web/ui/public/javascripts/components/turbo_tracker.js */let turboIsOperating=!1;function isTurboOperating(){return turboIsOperating}
|
|
62
62
|
/*! Source: lib/karafka/web/ui/public/javascripts/application.js */function updateTimeAgo(){0!=(e=document.querySelectorAll("time")).length&&(timeago.render(e),timeago.cancel());for(var e=document.getElementsByClassName("time-title"),t=0;t<e.length;t++){var i=e[t],s=i.getAttribute("title");i.setAttribute("title",timeago.format(s))}}function refreshTitle(){var e=document.querySelectorAll(".breadcrumbs a"),e=Array.from(e).slice(1).map(e=>e.textContent.trim());0<e.length?document.title=e.join(" > ")+" - Karafka Web UI":document.title="Karafka Web UI"}function redirectToPartition(){var e=document.getElementById("current-partition");null!=e&&e.addEventListener("change",function(){Turbo.visit(this.value)})}function bindActionsConfirmations(){for(var t=document.getElementsByClassName("confirm-action"),i=0;i<t.length;i++){var s=t[i];let e="click";"FORM"===s.nodeName&&(e="submit"),s.addEventListener(e,function(e){window.confirm("Are you sure?")||e.preventDefault()})}}function bindLockableButtons(){document.querySelectorAll(".btn-lockable").forEach(function(i){i.addEventListener("click",function(e){var t=i.closest("form");t?t.addEventListener("submit",function(){i.disabled=!0,i.textContent+="...",document.querySelectorAll(".modal").forEach(function(e){e.classList.add("modal-locked")})},{once:!0}):(i.disabled=!0,i.textContent+="...")})})}function addListeners(){initLivePolling(),bindPollingButtonClick(),bindLockableButtons(),setLivePollButton(),setPollingListener(),hljs.highlightAll(),updateTimeAgo(),redirectToPartition(),(new TabsManager).manageTabs(),manageCharts(),bindActionsConfirmations(),loadOffsetLookupDatePicker(),new BtnToggleManager,new BtnToggleManager(".btn-toggle-nav-collapsed","collapsed"),new ThemeManager,refreshTitle(),new SearchMetadataVisibilityManager,new SearchModalManager}document.addEventListener("turbo:visit",function(){turboIsOperating=!0}),document.addEventListener("turbo:before-fetch-request",function(){turboIsOperating=!0}),document.addEventListener("turbo:before-fetch-response",function(){turboIsOperating=!0}),document.addEventListener("turbo:load",function(){turboIsOperating=!1}),document.addEventListener("turbo:frame-load",function(){turboIsOperating=!1}),document.addEventListener("turbo:frame-render",function(){turboIsOperating=!1}),document.addEventListener("turbo:load",addListeners),Turbo.setProgressBarDelay(100)
|
|
63
63
|
/*! Source: lib/karafka/web/ui/public/javascripts/charts/types/bar.js */;class BarChartManager{constructor(){this.datasetStateManager=new DatasetStateManager}refreshAndRenderBarCharts(c,u=!1){(u?c:document).querySelectorAll(".chartjs-bar").forEach(e=>{var t=e.id,i=(u?c:document).getElementById(t),s=JSON.parse(i.dataset.datasets);let r=[],a=[],n=[];var o=i.dataset.label_type_y;let l=i.dataset.label_type_x,h=this.datasetStateManager.getCurrentChart(t);Object.entries(s).forEach(([e,t],i)=>{t.forEach(([e,t])=>{n.push(t),0===i&&r.push(DataFormattingUtils.formatLabelX(e,l))}),a.push({data:t.map(([,e])=>e),label:e,hidden:h.includes(i),borderWidth:2.5})});var i=Math.min(...n),s=Math.max(...n),i=Math.round(i-.1*i),s=Math.round(s+.005*s),d=Math.round(n.reduce((e,t)=>e+t,0)/n.length);a.push({type:"line",label:"Average",data:new Array(r.length).fill(d),borderWidth:2,fill:!1,pointRadius:0,hoverBorderWidth:3,pointHitRadius:20}),u?((d=Chart.getChart(t)).data.datasets=a,d.data.labels=r,d.options.scales.y.min=i,d.options.scales.y.max=s,d.update("none")):this.renderBarChart(e,r,a,i,s,o)})}renderBarChart(e,t,i,s,r,a){new Chart(e,{type:"bar",data:{labels:t,datasets:i},options:{responsive:!0,maintainAspectRatio:!1,aspectRatio:5,scales:{x:{display:!0},y:{beginAtZero:!1,min:s,max:r,ticks:{maxTicksLimit:8,callback:function(e,t,i){return DataFormattingUtils.formatLabelY(a,e,t,i)}}}},animation:!1,animations:{colors:!1,x:!1},transitions:{active:{animation:{duration:!1}}},plugins:{legend:{position:"hidden"},tooltip:{callbacks:{label:function(e){let t=e.dataset.label||"";return"Average"!==t?DataFormattingUtils.formatTooltip(a,e):t+=": "+e.formattedValue}}}}}})}}
|
|
64
|
-
/*! Source: lib/karafka/web/ui/public/javascripts/charts/types/line.js */class LineChartsManager{constructor(){this.datasetStateManager=new DatasetStateManager}getLegendHeightPercentage(e){var t=e.chartArea,e=e.height,t=e-(t.bottom-t.top);return Math.round(t/e*100)}afterRenderPlugin(){let i=this;return{id:"afterRender",afterRender:function(e){var t=i.getLegendHeightPercentage(e),e=document.getElementById(e.canvas.id);50<t&&""==e.parentElement.style.height&&(e.parentElement.style.height="400px")}}}refreshAndRender(d,c=!1){(c?d:document).querySelectorAll(".chartjs-line").forEach(e=>{var t=e.id,i=(c?d:document).getElementById(t),s=JSON.parse(i.dataset.datasets);let r=[],a=[],n=0;var o=i.dataset.label_type_y;let l=i.dataset.label_type_x,h=this.datasetStateManager.getCurrentChart(t);Object.entries(s).forEach(([e,t],i)=>{t.forEach(([e,t])=>{0===i&&r.push(DataFormattingUtils.formatLabelX(e,l)),DataFormattingUtils.isFractionalPrecision(t)&&(n=2)}),a.push({data:t,label:e,hidden:h.includes(i),borderWidth:2.5,pointHitRadius:10})}),c?((i=Chart.getChart(t)).data.datasets=a,i.data.labels=r,i.update("none")):this.render(e,r,a,n,o)})}render(e,t,i,s,r){var a=null,a=10<i.length?"point":"x";new Chart(e,{type:"line",data:{labels:t,datasets:i},options:{responsive:!0,maintainAspectRatio:!1,aspectRatio:5,title:{display:!1},interaction:{mode:"nearest",axis:"x",intersect:!1},animation:!1,transitions:{active:{animation:{duration:!1}}},plugins:{legend:{position:"bottom",labels:{padding:20},onClick:(e,t,i)=>{var s=t.datasetIndex,i=i.chart;i.isDatasetVisible(s)?(i.hide(s),t.hidden=!0):(i.show(s),t.hidden=!1),this.datasetStateManager.saveCurrent()}},tooltip:{mode:a,filter:function(e,t,i){return t<10},callbacks:{label:function(e){return DataFormattingUtils.formatTooltip(r,e)}}}},scales:{x:{display:!1},y:{ticks:{precision:s,count:5,callback:function(e,t,i){return DataFormattingUtils.formatLabelY(r,e,t,i)}}}},elements:{point:{radius:0,style:!1},line:{style:"star",radius:0,spanGaps:!1}},hover:{mode:"index",intersect:!1}},plugins:[this.afterRenderPlugin()]})}}
|
|
64
|
+
/*! Source: lib/karafka/web/ui/public/javascripts/charts/types/line.js */class LineChartsManager{constructor(){this.datasetStateManager=new DatasetStateManager}getLegendHeightPercentage(e){var t=e.chartArea,e=e.height,t=e-(t.bottom-t.top);return Math.round(t/e*100)}afterRenderPlugin(){let i=this;return{id:"afterRender",afterRender:function(e){var t=i.getLegendHeightPercentage(e),e=document.getElementById(e.canvas.id);50<t&&""==e.parentElement.style.height&&(e.parentElement.style.height="400px")}}}refreshAndRender(d,c=!1){(c?d:document).querySelectorAll(".chartjs-line").forEach(e=>{var t=e.id,i=(c?d:document).getElementById(t),s=JSON.parse(i.dataset.datasets);let r=[],a=[],n=0;var o=i.dataset.label_type_y;let l=i.dataset.label_type_x,h=this.datasetStateManager.getCurrentChart(t);Object.entries(s).forEach(([e,t],i)=>{t.forEach(([e,t])=>{0===i&&r.push(DataFormattingUtils.formatLabelX(e,l)),DataFormattingUtils.isFractionalPrecision(t)&&(n=2)}),a.push({data:t,label:e,hidden:h.includes(i),borderWidth:2.5,pointHitRadius:10})}),c?((i=Chart.getChart(t)).data.datasets=a,i.data.labels=r,i.update("none")):this.render(e,r,a,n,o)})}render(e,t,i,s,r){var a=null,a=10<i.length?"point":"x";new Chart(e,{type:"line",data:{labels:t,datasets:i},options:{responsive:!0,maintainAspectRatio:!1,aspectRatio:5,title:{display:!1},interaction:{mode:"nearest",axis:"x",intersect:!1},animation:!1,transitions:{active:{animation:{duration:!1}}},plugins:{legend:{position:"bottom",labels:{padding:20},onClick:(e,t,i)=>{var s=t.datasetIndex,i=i.chart;i.isDatasetVisible(s)?(i.hide(s),t.hidden=!0):(i.show(s),t.hidden=!1),this.datasetStateManager.saveCurrent()}},tooltip:{mode:a,filter:function(e,t,i){return t<10},callbacks:{label:function(e){return DataFormattingUtils.formatTooltip(r,e)}}}},scales:{x:{display:!1},y:{ticks:{precision:s,count:5,callback:function(e,t,i){return DataFormattingUtils.formatLabelY(r,e,t,i)}}}},elements:{point:{radius:0,style:!1},line:{style:"star",radius:0,spanGaps:!1}},hover:{mode:"index",intersect:!1}},plugins:[this.afterRenderPlugin()]})}}
|
|
65
|
+
//# sourceMappingURL=application.min.js.map
|
|
Binary file
|
|
Binary file
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
'hidden' class on their target elements (defined by the data attribute `data-toggle-target`)
|
|
7
7
|
when clicked.
|
|
8
8
|
*/
|
|
9
|
+
|
|
9
10
|
class BtnToggleManager {
|
|
10
11
|
constructor(btnClass = '.btn-toggle', visibilityClass = 'hidden') {
|
|
11
12
|
this.btnClass = btnClass;
|
|
@@ -23,13 +24,22 @@ class BtnToggleManager {
|
|
|
23
24
|
// Establish initial state from local storage or based on visibility
|
|
24
25
|
this.restoreVisibility(button, targetElement);
|
|
25
26
|
|
|
26
|
-
//
|
|
27
|
-
button.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
// Check if the event listener has already been added
|
|
28
|
+
if (!button._isClickListenerAdded) {
|
|
29
|
+
// Define the event handler and store the flag to prevent duplicate listeners
|
|
30
|
+
const handleClick = () => {
|
|
31
|
+
const isVisible = !targetElement.classList.contains(this.visibilityClass);
|
|
32
|
+
targetElement.classList.toggle(this.visibilityClass);
|
|
33
|
+
button.classList.toggle('active', !isVisible);
|
|
34
|
+
this.saveVisibility(targetId, !isVisible);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Add the event listener
|
|
38
|
+
button.addEventListener('click', handleClick);
|
|
39
|
+
|
|
40
|
+
// Set flag to indicate the listener has been added
|
|
41
|
+
button._isClickListenerAdded = true;
|
|
42
|
+
}
|
|
33
43
|
});
|
|
34
44
|
}
|
|
35
45
|
|