karafka-web 0.10.0 → 0.10.2
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/.ruby-version +1 -1
- data/CHANGELOG.md +17 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +12 -4
- data/certs/cert.pem +26 -0
- data/karafka-web.gemspec +2 -2
- data/lib/karafka/web/pro/ui/app.rb +75 -0
- data/lib/karafka/web/pro/ui/controllers/commanding_controller.rb +4 -4
- data/lib/karafka/web/pro/ui/controllers/recurring_tasks_controller.rb +131 -0
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/base_controller.rb +29 -0
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/explorer_controller.rb +65 -0
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/schedules_controller.rb +84 -0
- data/lib/karafka/web/pro/ui/views/consumers/_consumer_controls.erb +13 -12
- data/lib/karafka/web/pro/ui/views/explorer/_partition_option.erb +10 -2
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_actions.erb +58 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_batch_actions.erb +45 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_breadcrumbs.erb +22 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_log.erb +26 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_not_active.erb +12 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_tabs.erb +17 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_task.erb +46 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/logs.erb +34 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/schedule.erb +43 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_breadcrumbs.erb +30 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_message.erb +84 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_messages.erb +28 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/partition.erb +72 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/topic.erb +33 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/_breadcrumbs.erb +21 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/_no_groups.erb +11 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/index.erb +38 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/show.erb +48 -0
- data/lib/karafka/web/pro/ui/views/search/_breadcrumbs.erb +1 -0
- data/lib/karafka/web/pro/ui/views/shared/_navigation.erb +20 -0
- data/lib/karafka/web/pro/ui/views/topics/replication.erb +1 -1
- data/lib/karafka/web/tracking/consumers/listeners/errors.rb +3 -1
- data/lib/karafka/web/ui/base.rb +1 -1
- data/lib/karafka/web/ui/controllers/base_controller.rb +18 -3
- data/lib/karafka/web/ui/helpers/application_helper.rb +29 -8
- data/lib/karafka/web/ui/helpers/paths_helper.rb +18 -0
- data/lib/karafka/web/ui/models/recurring_tasks/log.rb +15 -0
- data/lib/karafka/web/ui/models/recurring_tasks/schedule.rb +75 -0
- data/lib/karafka/web/ui/models/recurring_tasks/task.rb +19 -0
- data/lib/karafka/web/ui/public/javascripts/application.js +1 -1
- data/lib/karafka/web/ui/public/javascripts/application.min.js +7 -7
- 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/live_poll.js +51 -0
- data/lib/karafka/web/ui/public/stylesheets/application.css +5 -1
- data/lib/karafka/web/ui/public/stylesheets/application.min.css +2 -2
- 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/ui/public/stylesheets/libs/tailwind.css +18 -6
- data/lib/karafka/web/ui/views/dashboard/_ranges_selector.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_breadcrumbs.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_navigation.erb +21 -0
- data/lib/karafka/web/ui/views/shared/icons/_calendar.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_check.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_play.erb +3 -0
- data/lib/karafka/web/ui/views/status/info/_components.erb +48 -11
- data/lib/karafka/web/ui/views/ux/_data_table.erb +34 -4
- data/lib/karafka/web/ui/views/ux/_status_rows.erb +12 -0
- data/lib/karafka/web/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +56 -27
- metadata.gz.sig +0 -0
- data/certs/cert_chain.pem +0 -26
@@ -0,0 +1,58 @@
|
|
1
|
+
<%
|
2
|
+
trigger_path = root_path('recurring_tasks', task.id, 'trigger')
|
3
|
+
disabled_class = task.enabled? ? '' : 'btn-disabled'
|
4
|
+
%>
|
5
|
+
<form
|
6
|
+
action="<%= trigger_path %>"
|
7
|
+
method="post"
|
8
|
+
class="inline"
|
9
|
+
>
|
10
|
+
<%== csrf_tag(trigger_path) %>
|
11
|
+
<button
|
12
|
+
type="submit"
|
13
|
+
class="btn btn-primary btn-sm "
|
14
|
+
title="Trigger"
|
15
|
+
>
|
16
|
+
<%== icon(:play) %>
|
17
|
+
</button>
|
18
|
+
</form>
|
19
|
+
|
20
|
+
<%
|
21
|
+
enable_path = root_path('recurring_tasks', task.id, 'enable')
|
22
|
+
disabled_class = task.enabled? ? 'btn-disabled' : ''
|
23
|
+
%>
|
24
|
+
<form
|
25
|
+
action="<%= enable_path %>"
|
26
|
+
method="post"
|
27
|
+
class="inline"
|
28
|
+
title="Enable"
|
29
|
+
>
|
30
|
+
<%== csrf_tag(enable_path) %>
|
31
|
+
<button
|
32
|
+
type="submit"
|
33
|
+
class="btn btn-success btn-sm <%= disabled_class %>"
|
34
|
+
>
|
35
|
+
<%== icon(:check) %>
|
36
|
+
</button>
|
37
|
+
</form>
|
38
|
+
|
39
|
+
<%
|
40
|
+
disable_path = root_path('recurring_tasks', task.id, 'disable')
|
41
|
+
disabled_class = task.enabled? ? '' : 'btn-disabled'
|
42
|
+
%>
|
43
|
+
<form
|
44
|
+
action="<%= disable_path %>"
|
45
|
+
method="post"
|
46
|
+
class="inline"
|
47
|
+
title="Disable"
|
48
|
+
|
49
|
+
>
|
50
|
+
<%== csrf_tag(disable_path) %>
|
51
|
+
<button
|
52
|
+
type="submit"
|
53
|
+
class="btn btn-warning btn-sm <%= disabled_class %>"
|
54
|
+
|
55
|
+
>
|
56
|
+
<%== icon(:pause) %>
|
57
|
+
</button>
|
58
|
+
</form>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<div class="col-span-12 flex justify-end space-x-2 mb-6">
|
2
|
+
<%
|
3
|
+
trigger_all_path = root_path('recurring_tasks', 'trigger_all')
|
4
|
+
disable_class = @tasks.empty? ? 'btn-disabled' : ''
|
5
|
+
%>
|
6
|
+
<form
|
7
|
+
action="<%= trigger_all_path %>"
|
8
|
+
method="post"
|
9
|
+
class="inline-flex items-center"
|
10
|
+
>
|
11
|
+
<%== csrf_tag(trigger_all_path) %>
|
12
|
+
<button type="submit" class="btn btn-primary btn-sm <%= disable_class %>">
|
13
|
+
<%== icon(:play) %>
|
14
|
+
Trigger All
|
15
|
+
</button>
|
16
|
+
</form>
|
17
|
+
|
18
|
+
<%
|
19
|
+
enable_all_path = root_path('recurring_tasks', 'enable_all')
|
20
|
+
disable_class = @tasks.all?(&:enabled?) ? 'btn-disabled' : ''
|
21
|
+
%>
|
22
|
+
<form
|
23
|
+
action="<%= enable_all_path %>"
|
24
|
+
method="post"
|
25
|
+
class="inline-flex items-center"
|
26
|
+
>
|
27
|
+
<%== csrf_tag(enable_all_path) %>
|
28
|
+
<button type="submit" class="btn btn-success btn-sm <%= disable_class %>">
|
29
|
+
<%== icon(:check) %>
|
30
|
+
Enable All
|
31
|
+
</button>
|
32
|
+
</form>
|
33
|
+
|
34
|
+
<%
|
35
|
+
disable_all_path = root_path('recurring_tasks', 'disable_all')
|
36
|
+
disable_class = @tasks.none?(&:enabled?) ? 'btn-disabled' : ''
|
37
|
+
%>
|
38
|
+
<form action="<%= disable_all_path %>" method="post" class="inline-flex items-center">
|
39
|
+
<%== csrf_tag(disable_all_path) %>
|
40
|
+
<button type="submit" class="btn btn-warning btn-sm <%= disable_class %>">
|
41
|
+
<%== icon(:pause) %>
|
42
|
+
Disable All
|
43
|
+
</button>
|
44
|
+
</form>
|
45
|
+
</div>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<li>
|
2
|
+
<a href="<%= root_path('recurring_tasks') %>">
|
3
|
+
Recurring Tasks
|
4
|
+
</a>
|
5
|
+
</li>
|
6
|
+
|
7
|
+
<% if current_path.include?('/schedule') %>
|
8
|
+
<li>
|
9
|
+
<a href="<%= root_path('recurring_tasks/schedule') %>">
|
10
|
+
Schedule
|
11
|
+
<%= @schedule ? @schedule.schedule_version : '' %>
|
12
|
+
</a>
|
13
|
+
</li>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<% if current_path.include?('/logs') %>
|
17
|
+
<li>
|
18
|
+
<a href="<%= root_path('recurring_tasks/logs') %>">
|
19
|
+
Logs
|
20
|
+
</a>
|
21
|
+
</li>
|
22
|
+
<% end %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<% result = log.task[:result] == 'success' %>
|
2
|
+
<tr class="<%= result ? '' : 'status-row-error' %>">
|
3
|
+
<td>
|
4
|
+
<%= log.id %>
|
5
|
+
</td>
|
6
|
+
<td>
|
7
|
+
<% if result %>
|
8
|
+
<%== badge_success 'Success' %>
|
9
|
+
<% else %>
|
10
|
+
<%== badge_error 'Error' %>
|
11
|
+
<% end %>
|
12
|
+
</td>
|
13
|
+
<td>
|
14
|
+
<% if result %>
|
15
|
+
<%== log.task[:time_taken].round(2) %> ms
|
16
|
+
<% else %>
|
17
|
+
N/A
|
18
|
+
<% end %>
|
19
|
+
</td>
|
20
|
+
<td>
|
21
|
+
<%== relative_time log.dispatched_at %>
|
22
|
+
</td>
|
23
|
+
<td>
|
24
|
+
<%= log.schedule_version %>
|
25
|
+
</td>
|
26
|
+
</tr>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% alert_box_info('Recurring Tasks Data Unavailable') do %>
|
2
|
+
<p class="mb-2">
|
3
|
+
We are unable to display data related to recurring tasks. Please ensure that:
|
4
|
+
</p>
|
5
|
+
|
6
|
+
<ul class="list-disc list-inside">
|
7
|
+
<li>Recurring Tasks are enabled in your routing configuration.</li>
|
8
|
+
<li>The necessary Kafka topics have been created.</li>
|
9
|
+
<li>A schedule has been defined.</li>
|
10
|
+
<li>Your Karafka server, with schedule awareness, is running and has persisted the state.</li>
|
11
|
+
</ul>
|
12
|
+
<% end %>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class="col-span-12 mb-9">
|
2
|
+
<div class="tab-container">
|
3
|
+
<a
|
4
|
+
href="<%= root_path('recurring_tasks', 'schedule') %>"
|
5
|
+
class="custom-tab <%= nav_class(include: 'schedule') %>"
|
6
|
+
>
|
7
|
+
Schedules
|
8
|
+
</a>
|
9
|
+
|
10
|
+
<a
|
11
|
+
href="<%= root_path('recurring_tasks', 'logs') %>"
|
12
|
+
class="custom-tab <%= nav_class(include: '/logs') %>"
|
13
|
+
>
|
14
|
+
Logs
|
15
|
+
</a>
|
16
|
+
</div>
|
17
|
+
</div>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<tr class="<%= task.enabled? ? '' : 'status-row-warning text-muted' %>">
|
2
|
+
<td>
|
3
|
+
<%= task.id %>
|
4
|
+
</td>
|
5
|
+
|
6
|
+
<td>
|
7
|
+
<% if task.enabled? %>
|
8
|
+
<%== badge_success('Enabled') %>
|
9
|
+
<% else %>
|
10
|
+
<%== badge_warning('Disabled') %>
|
11
|
+
<% end %>
|
12
|
+
</td>
|
13
|
+
|
14
|
+
<td>
|
15
|
+
<code><%= task.cron %></code>
|
16
|
+
</td>
|
17
|
+
|
18
|
+
<td>
|
19
|
+
<% if task.previous_time.positive? %>
|
20
|
+
<%== relative_time task.previous_time %>
|
21
|
+
<% else %>
|
22
|
+
Never
|
23
|
+
<% end %>
|
24
|
+
</td>
|
25
|
+
|
26
|
+
<td>
|
27
|
+
<% if task.enabled? %>
|
28
|
+
<% if task.next_time < Time.now.to_i %>
|
29
|
+
Right now
|
30
|
+
<% else %>
|
31
|
+
<%== relative_time task.next_time %>
|
32
|
+
<% end %>
|
33
|
+
<% else %>
|
34
|
+
Never
|
35
|
+
<% end %>
|
36
|
+
</td>
|
37
|
+
|
38
|
+
<td class="commands-inline-3">
|
39
|
+
<%==
|
40
|
+
partial(
|
41
|
+
'recurring_tasks/actions',
|
42
|
+
locals: { task: task }
|
43
|
+
)
|
44
|
+
%>
|
45
|
+
</td>
|
46
|
+
</tr>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<% view_title 'Logs' %>
|
2
|
+
|
3
|
+
<%== partial 'recurring_tasks/tabs' %>
|
4
|
+
|
5
|
+
<div class="col-span-12">
|
6
|
+
<% if @logs.empty? && params.current_page <= 1 %>
|
7
|
+
<%== alert_info('There are no available logs.') %>
|
8
|
+
<% elsif @logs.empty? %>
|
9
|
+
<%== partial 'shared/no_paginated_data' %>
|
10
|
+
<% else %>
|
11
|
+
<div class="data-table-wrapper">
|
12
|
+
<table class="data-table">
|
13
|
+
<thead>
|
14
|
+
<tr>
|
15
|
+
<th>Task ID</th>
|
16
|
+
<th>Result</th>
|
17
|
+
<th>Time Taken</th>
|
18
|
+
<th>Dispatched At</th>
|
19
|
+
<th>Schedule Version</th>
|
20
|
+
</tr>
|
21
|
+
</thead>
|
22
|
+
<tbody>
|
23
|
+
<%==
|
24
|
+
render_each(
|
25
|
+
@logs,
|
26
|
+
'recurring_tasks/_log',
|
27
|
+
local: :log
|
28
|
+
)
|
29
|
+
%>
|
30
|
+
</tbody>
|
31
|
+
</table>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
34
|
+
</div>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<% if @schedule %>
|
2
|
+
<% view_title "Schedule #{@schedule.schedule_version}" %>
|
3
|
+
<% else %>
|
4
|
+
<% view_title 'Schedule' %>
|
5
|
+
<% end %>
|
6
|
+
|
7
|
+
<% if @schedule %>
|
8
|
+
<%== partial 'recurring_tasks/tabs' %>
|
9
|
+
|
10
|
+
<% unless @tasks.empty? %>
|
11
|
+
<%== partial 'recurring_tasks/batch_actions' %>
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<div class="col-span-12">
|
16
|
+
<% if @schedule && !@tasks.empty? %>
|
17
|
+
<div class="data-table-wrapper">
|
18
|
+
<table class="data-table">
|
19
|
+
<thead>
|
20
|
+
<tr>
|
21
|
+
<th><%== sort_link('Task ID', :id) %></th>
|
22
|
+
<th><%== sort_link('Status', :enabled) %></th>
|
23
|
+
<th><%== sort_link(:cron) %></th>
|
24
|
+
<th><%== sort_link(:previous_time) %></th>
|
25
|
+
<th><%== sort_link(:next_time) %></th>
|
26
|
+
<th></th>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<%==
|
31
|
+
render_each(
|
32
|
+
@tasks,
|
33
|
+
'recurring_tasks/_task',
|
34
|
+
local: :task
|
35
|
+
)
|
36
|
+
%>
|
37
|
+
</tbody>
|
38
|
+
</table>
|
39
|
+
</div>
|
40
|
+
<% else %>
|
41
|
+
<%== partial 'recurring_tasks/not_active' %>
|
42
|
+
<% end %>
|
43
|
+
</div>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<li>
|
2
|
+
<a href="<%= root_path('scheduled_messages') %>">
|
3
|
+
Scheduled Messages
|
4
|
+
</a>
|
5
|
+
</li>
|
6
|
+
|
7
|
+
<% if current_path.include?('/explorer') %>
|
8
|
+
<li>
|
9
|
+
<a href="<%= root_path("scheduled_messages/explorer/#{@topic_id}") %>">
|
10
|
+
Messages
|
11
|
+
</a>
|
12
|
+
</li>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<% if @topic_id %>
|
16
|
+
<li>
|
17
|
+
<a href="<%= root_path("scheduled_messages/explorer/#{@topic_id}") %>">
|
18
|
+
<%= @topic_id %>
|
19
|
+
</a>
|
20
|
+
</li>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<% if @partition_id %>
|
24
|
+
<li>
|
25
|
+
<a href="<%= root_path("scheduled_messages/explorer/#{@topic_id}/#{@partition_id}") %>">
|
26
|
+
Partition
|
27
|
+
<%= @partition_id %>
|
28
|
+
</a>
|
29
|
+
</li>
|
30
|
+
<% end %>
|
@@ -0,0 +1,84 @@
|
|
1
|
+
<% safe_key = ::Karafka::Web::Pro::Ui::Lib::SafeRunner.new { message.key } %>
|
2
|
+
|
3
|
+
<% if message.is_a?(Array) %>
|
4
|
+
<tr>
|
5
|
+
<td class="text-muted">
|
6
|
+
<%= message[0] %>
|
7
|
+
</td>
|
8
|
+
<td class="text-muted">
|
9
|
+
<%= message[1] %>
|
10
|
+
</td>
|
11
|
+
<td colspan="8" class="text-center text-muted">
|
12
|
+
This offset does not contain any data. The message may have been compacted or is a system entry.
|
13
|
+
</td>
|
14
|
+
</tr>
|
15
|
+
<% else %>
|
16
|
+
<% type = message.headers['schedule_source_type'] %>
|
17
|
+
<tr>
|
18
|
+
<td>
|
19
|
+
<%= message.partition %>
|
20
|
+
</td>
|
21
|
+
<td>
|
22
|
+
<%= message.offset %>
|
23
|
+
</td>
|
24
|
+
<td>
|
25
|
+
<% if type == 'tombstone' %>
|
26
|
+
<%== badge_secondary type %>
|
27
|
+
<% end %>
|
28
|
+
|
29
|
+
<% if type == 'cancel' %>
|
30
|
+
<%== badge_warning type %>
|
31
|
+
<% end %>
|
32
|
+
|
33
|
+
<% if type == 'schedule' %>
|
34
|
+
<%== badge_primary type %>
|
35
|
+
<% end %>
|
36
|
+
</td>
|
37
|
+
<td>
|
38
|
+
<%= message.headers['schedule_schema_version'] %>
|
39
|
+
</td>
|
40
|
+
|
41
|
+
<% if type == 'cancel' %>
|
42
|
+
<td colspan="5" class="text-center text-muted">
|
43
|
+
Cancellation messages do not contain those details.
|
44
|
+
</td>
|
45
|
+
<% else %>
|
46
|
+
<td>
|
47
|
+
<%== relative_time(message.timestamp) %>
|
48
|
+
</td>
|
49
|
+
<td>
|
50
|
+
<%== relative_time message.headers['schedule_target_epoch'].to_i %>
|
51
|
+
</td>
|
52
|
+
<td>
|
53
|
+
<% if @visibility_filter.key?(message) %>
|
54
|
+
<% if safe_key.success? %>
|
55
|
+
<%= safe_key.result %>
|
56
|
+
<% else %>
|
57
|
+
<span class="text-muted">[Deserialization Failed]</span>
|
58
|
+
<% end %>
|
59
|
+
<% else %>
|
60
|
+
<span class="text-muted">[Filtered]</span>
|
61
|
+
<% end %>
|
62
|
+
</td>
|
63
|
+
<td>
|
64
|
+
<%= message.headers['schedule_target_topic'] %>
|
65
|
+
</td>
|
66
|
+
<td>
|
67
|
+
<% if @visibility_filter.key?(message) %>
|
68
|
+
<%= message.headers['schedule_target_key'] %>
|
69
|
+
<% else %>
|
70
|
+
<span class="text-muted">[Filtered]</span>
|
71
|
+
<% end %>
|
72
|
+
</td>
|
73
|
+
<% end %>
|
74
|
+
|
75
|
+
<td>
|
76
|
+
<%==
|
77
|
+
link_button_primary_sm(
|
78
|
+
'Details',
|
79
|
+
explorer_path(message.topic, message.partition, message.offset)
|
80
|
+
)
|
81
|
+
%>
|
82
|
+
</td>
|
83
|
+
</tr>
|
84
|
+
<% end %>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<div class="data-table-wrapper">
|
2
|
+
<table class="data-table">
|
3
|
+
<thead>
|
4
|
+
<tr>
|
5
|
+
<th>Partition</th>
|
6
|
+
<th>Offset</th>
|
7
|
+
<th>Type</th>
|
8
|
+
<th>Schema</th>
|
9
|
+
<th>Created At</th>
|
10
|
+
<th>Dispatch At</th>
|
11
|
+
<th>Key</th>
|
12
|
+
<th>Target Topic</th>
|
13
|
+
<th>Target Key</th>
|
14
|
+
<th></th>
|
15
|
+
</tr>
|
16
|
+
</thead>
|
17
|
+
<tbody>
|
18
|
+
<%==
|
19
|
+
each_partial(
|
20
|
+
@messages,
|
21
|
+
'scheduled_messages/explorer/message'
|
22
|
+
)
|
23
|
+
%>
|
24
|
+
</tbody>
|
25
|
+
</table>
|
26
|
+
|
27
|
+
<%== content_for :table_metadata %>
|
28
|
+
</div>
|
@@ -0,0 +1,72 @@
|
|
1
|
+
<% view_title "#{@topic_id} partition #{@partition_id}" %>
|
2
|
+
|
3
|
+
<% @selector_path_method = :scheduled_messages_explorer_path %>
|
4
|
+
|
5
|
+
<div class="col-span-4">
|
6
|
+
<section class="actions">
|
7
|
+
<% if @messages && !@messages.empty? %>
|
8
|
+
<a
|
9
|
+
href="<%= explorer_path(@topic_id, @partition_id, 'recent') %>"
|
10
|
+
class="btn-action"
|
11
|
+
title="Display the most recent message for this partition with auto-refresh"
|
12
|
+
>
|
13
|
+
<%== icon(:play_circle) %>
|
14
|
+
</a>
|
15
|
+
|
16
|
+
<a
|
17
|
+
href="<%= explorer_path(@topic_id, 'search', "?partition=#{@partition_id}") %>"
|
18
|
+
class="btn-action"
|
19
|
+
title="Search in this topic"
|
20
|
+
>
|
21
|
+
<%== icon(:magnifying_glass) %>
|
22
|
+
</a>
|
23
|
+
|
24
|
+
<% closest_path = scheduled_messages_explorer_path(@topic_id, @partition_id) %>
|
25
|
+
<input
|
26
|
+
type="image"
|
27
|
+
src="<%= asset_path('images/calendar.svg') %>"
|
28
|
+
width="45"
|
29
|
+
height="32"
|
30
|
+
class="btn-action p-1 opacity-60"
|
31
|
+
id="offset-lookup-datepicker"
|
32
|
+
value=""
|
33
|
+
data-target="<%= closest_path %>"
|
34
|
+
/>
|
35
|
+
<% end %>
|
36
|
+
</section>
|
37
|
+
</div>
|
38
|
+
|
39
|
+
<div class="col-span-8 mb-3">
|
40
|
+
<section class="actions">
|
41
|
+
<%== partial 'explorer/selector' %>
|
42
|
+
</section>
|
43
|
+
</div>
|
44
|
+
|
45
|
+
<div class="col-span-12">
|
46
|
+
<% if @limited %>
|
47
|
+
<%== partial('explorer/topic/limited') %>
|
48
|
+
<% end %>
|
49
|
+
|
50
|
+
<% if @watermark_offsets.empty? && params.current_page == 1 %>
|
51
|
+
<%== partial 'explorer/partition/empty' %>
|
52
|
+
<% elsif @watermark_offsets.cleaned? && params.current_page == 1 %>
|
53
|
+
<%== partial 'explorer/partition/cleaned' %>
|
54
|
+
<% elsif @messages.empty? %>
|
55
|
+
<%== partial 'shared/no_paginated_data' %>
|
56
|
+
<% else %>
|
57
|
+
<% content_for :table_metadata do %>
|
58
|
+
<p class="table_metadata">
|
59
|
+
Watermark offsets:
|
60
|
+
<span class="badge badge-secondary mt-1 mb-1">
|
61
|
+
high: <%= @watermark_offsets.high %>
|
62
|
+
</span>
|
63
|
+
|
64
|
+
<span class="badge badge-secondary mt-1 mb-1">
|
65
|
+
low: <%= @watermark_offsets.low %>
|
66
|
+
</span>
|
67
|
+
</p>
|
68
|
+
<% end %>
|
69
|
+
|
70
|
+
<%== partial('scheduled_messages/explorer/messages') %>
|
71
|
+
<% end %>
|
72
|
+
</div>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<% view_title @topic_id %>
|
2
|
+
|
3
|
+
<% @selector_path_method = :scheduled_messages_explorer_path %>
|
4
|
+
|
5
|
+
<%== partial 'explorer/topic/actions' %>
|
6
|
+
|
7
|
+
<div class="col-span-12">
|
8
|
+
<% if @limited %>
|
9
|
+
<div class="mb-6">
|
10
|
+
<%== partial('explorer/topic/limited') %>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<% if @messages.empty? && params.current_page == 1 %>
|
15
|
+
<%== partial 'explorer/topic/empty' %>
|
16
|
+
<% elsif @messages.empty? %>
|
17
|
+
<%== partial 'shared/no_paginated_data' %>
|
18
|
+
<% else %>
|
19
|
+
<% content_for :table_metadata do %>
|
20
|
+
<p class="table_metadata">
|
21
|
+
Partitions:
|
22
|
+
|
23
|
+
<%== badge("total: #{@partitions_count}") %>
|
24
|
+
<%==
|
25
|
+
range = [@active_partitions.first, @active_partitions.last].uniq.join(' to ')
|
26
|
+
badge("visible: #{range}")
|
27
|
+
%>
|
28
|
+
</p>
|
29
|
+
<% end %>
|
30
|
+
|
31
|
+
<%== partial('scheduled_messages/explorer/messages') %>
|
32
|
+
<% end %>
|
33
|
+
</div>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<li>
|
2
|
+
<a href="<%= root_path('scheduled_messages') %>">
|
3
|
+
Scheduled Messages
|
4
|
+
</a>
|
5
|
+
</li>
|
6
|
+
|
7
|
+
<% if current_path.include?('/schedules') %>
|
8
|
+
<li>
|
9
|
+
<a href="<%= root_path('scheduled_messages/schedules') %>">
|
10
|
+
Schedules
|
11
|
+
</a>
|
12
|
+
</li>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<% if @schedule_name %>
|
16
|
+
<li>
|
17
|
+
<a href="<%= root_path("scheduled_messages/schedules/#{@schedule_name}") %>">
|
18
|
+
<%= @schedule_name %>
|
19
|
+
</a>
|
20
|
+
</li>
|
21
|
+
<% end %>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<% alert_box_info 'Scheduled Messages Data Not Available' do %>
|
2
|
+
<p class="mb-2">
|
3
|
+
We are unable to display data related to scheduled messages. Please ensure that:
|
4
|
+
</p>
|
5
|
+
|
6
|
+
<ul class="list-disc list-inside">
|
7
|
+
<li>Scheduled Messages are enabled in your routing configuration.</li>
|
8
|
+
<li>The necessary Kafka topics have been created.</li>
|
9
|
+
<li>Your Karafka server, with scheduled messages awareness, is running and has persisted the state.</li>
|
10
|
+
</ul>
|
11
|
+
<% end %>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<% view_title 'Schedules' %>
|
2
|
+
|
3
|
+
<div class="col-span-12">
|
4
|
+
<% if @topics.empty? %>
|
5
|
+
<%== partial 'scheduled_messages/schedules/no_groups' %>
|
6
|
+
<% else %>
|
7
|
+
<% @topics.each do |topic| %>
|
8
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
9
|
+
<div class="card-support">
|
10
|
+
<h3>
|
11
|
+
<%== icon(:calendar) %>
|
12
|
+
<span>
|
13
|
+
<%= topic.topic_name %>
|
14
|
+
/
|
15
|
+
<%= topic.partition_count %>
|
16
|
+
</span>
|
17
|
+
</h3>
|
18
|
+
|
19
|
+
<p class="flex justify-center space-x-2 mb-3">
|
20
|
+
<a
|
21
|
+
href="<%= root_path("scheduled_messages/schedules/#{topic.topic_name}") %>"
|
22
|
+
class="btn btn-primary btn-sm flex-1"
|
23
|
+
>
|
24
|
+
Planned
|
25
|
+
</a>
|
26
|
+
|
27
|
+
<a
|
28
|
+
href="<%= root_path("scheduled_messages/explorer/#{topic.topic_name}") %>"
|
29
|
+
class="btn btn-primary btn-sm flex-1"
|
30
|
+
>
|
31
|
+
Messages
|
32
|
+
</a>
|
33
|
+
</p>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
<% end %>
|
37
|
+
<% end %>
|
38
|
+
</div>
|