rails_mini_profiler 0.4.0 → 0.7.1
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/README.md +48 -34
- data/app/adapters/rails_mini_profiler/database_adapter.rb +16 -0
- data/app/controllers/rails_mini_profiler/application_controller.rb +9 -15
- data/app/controllers/rails_mini_profiler/profiled_requests_controller.rb +44 -14
- data/app/helpers/rails_mini_profiler/application_helper.rb +1 -1
- data/app/helpers/rails_mini_profiler/profiled_requests_helper.rb +10 -0
- data/app/javascript/images/check.svg +3 -0
- data/app/javascript/images/chevron.svg +3 -0
- data/app/javascript/images/copy.svg +6 -0
- data/app/javascript/images/filter.svg +1 -0
- data/app/javascript/images/logo_variant.svg +2 -2
- data/app/javascript/images/search.svg +4 -5
- data/app/javascript/js/checklist_controller.js +48 -0
- data/app/javascript/js/clipboard_controller.js +53 -0
- data/app/javascript/js/enable_controller.js +23 -0
- data/app/javascript/js/filter_controller.js +48 -0
- data/app/javascript/js/search_controller.js +18 -0
- data/app/javascript/js/select_controller.js +52 -0
- data/app/javascript/packs/rails-mini-profiler.js +69 -53
- data/app/javascript/stylesheets/components/buttons.scss +59 -0
- data/app/javascript/stylesheets/components/dropdown.scss +103 -0
- data/app/javascript/stylesheets/components/input.scss +10 -0
- data/app/javascript/stylesheets/{navbar.scss → components/navbar.scss} +7 -13
- data/app/javascript/stylesheets/components/page_header.scss +7 -0
- data/app/javascript/stylesheets/components/pagination.scss +14 -13
- data/app/javascript/stylesheets/components/placeholder.scss +36 -0
- data/app/javascript/stylesheets/components/profiled_request_table.scss +55 -0
- data/app/javascript/stylesheets/components/trace.scss +93 -0
- data/app/javascript/stylesheets/flamegraph.scss +3 -2
- data/app/javascript/stylesheets/flashes.scss +3 -5
- data/app/javascript/stylesheets/profiled_requests.scss +12 -161
- data/app/javascript/stylesheets/rails-mini-profiler.scss +81 -66
- data/app/javascript/stylesheets/traces.scss +52 -56
- data/app/models/rails_mini_profiler/profiled_request.rb +1 -1
- data/app/models/rails_mini_profiler/trace.rb +0 -15
- data/app/presenters/rails_mini_profiler/controller_trace_presenter.rb +10 -2
- data/app/presenters/rails_mini_profiler/instantiation_trace_presenter.rb +15 -3
- data/app/presenters/rails_mini_profiler/profiled_request_presenter.rb +10 -17
- data/app/presenters/rails_mini_profiler/render_partial_trace_presenter.rb +6 -2
- data/app/presenters/rails_mini_profiler/render_template_trace_presenter.rb +6 -2
- data/app/presenters/rails_mini_profiler/sequel_trace_presenter.rb +16 -4
- data/app/presenters/rails_mini_profiler/trace_presenter.rb +10 -8
- data/app/search/rails_mini_profiler/base_search.rb +67 -0
- data/app/search/rails_mini_profiler/profiled_request_search.rb +33 -0
- data/app/search/rails_mini_profiler/trace_search.rb +27 -0
- data/app/views/rails_mini_profiler/badge.html.erb +2 -2
- data/app/views/rails_mini_profiler/profiled_requests/index.html.erb +8 -58
- data/app/views/rails_mini_profiler/profiled_requests/shared/header/_header.erb +19 -0
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_placeholder.erb +12 -0
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table.erb +14 -0
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table_head.erb +125 -0
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table_row.erb +21 -0
- data/app/views/rails_mini_profiler/profiled_requests/{shared → show}/_trace.html.erb +24 -7
- data/app/views/rails_mini_profiler/profiled_requests/show/_trace_list.erb +12 -0
- data/app/views/rails_mini_profiler/profiled_requests/show/_trace_list_header.erb +87 -0
- data/app/views/rails_mini_profiler/profiled_requests/show/_trace_list_placeholder.erb +12 -0
- data/app/views/rails_mini_profiler/profiled_requests/show.html.erb +5 -18
- data/app/views/rails_mini_profiler/shared/_head.erb +1 -1
- data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb +2 -0
- data/lib/rails_mini_profiler/badge.rb +21 -12
- data/lib/rails_mini_profiler/configuration/user_interface.rb +31 -1
- data/lib/rails_mini_profiler/configuration.rb +7 -0
- data/lib/rails_mini_profiler/engine.rb +12 -8
- data/lib/rails_mini_profiler/flamegraph_guard.rb +10 -6
- data/lib/rails_mini_profiler/guard.rb +19 -1
- data/lib/rails_mini_profiler/middleware.rb +12 -10
- data/lib/rails_mini_profiler/request_context.rb +22 -18
- data/lib/rails_mini_profiler/request_wrapper.rb +12 -55
- data/lib/rails_mini_profiler/response_wrapper.rb +21 -17
- data/lib/rails_mini_profiler/tracers/controller_tracer.rb +29 -0
- data/lib/rails_mini_profiler/tracers/instantiation_tracer.rb +17 -0
- data/lib/rails_mini_profiler/tracers/null_trace.rb +7 -0
- data/lib/rails_mini_profiler/tracers/registry.rb +76 -0
- data/lib/rails_mini_profiler/tracers/rmp_tracer.rb +17 -0
- data/lib/rails_mini_profiler/tracers/sequel_tracer.rb +51 -0
- data/lib/rails_mini_profiler/tracers/sequel_tracker.rb +40 -0
- data/lib/rails_mini_profiler/tracers/subscriptions.rb +28 -0
- data/lib/rails_mini_profiler/{models → tracers}/trace.rb +11 -3
- data/lib/rails_mini_profiler/tracers/trace_factory.rb +27 -0
- data/lib/rails_mini_profiler/tracers/tracer.rb +45 -0
- data/lib/rails_mini_profiler/tracers/view_tracer.rb +29 -0
- data/lib/rails_mini_profiler/tracers.rb +12 -83
- data/lib/rails_mini_profiler/user.rb +1 -1
- data/lib/rails_mini_profiler/version.rb +1 -1
- data/lib/rails_mini_profiler.rb +4 -8
- data/vendor/assets/images/check.svg +3 -0
- data/vendor/assets/images/chevron.svg +3 -0
- data/vendor/assets/images/copy.svg +6 -0
- data/vendor/assets/images/filter.svg +1 -0
- data/vendor/assets/images/logo_variant.svg +2 -2
- data/vendor/assets/images/search.svg +4 -5
- data/vendor/assets/javascripts/rails-mini-profiler.css +1 -1
- data/vendor/assets/javascripts/rails-mini-profiler.js +1 -1
- metadata +58 -13
- data/app/models/rails_mini_profiler/controller_trace.rb +0 -37
- data/app/models/rails_mini_profiler/instantiation_trace.rb +0 -37
- data/app/models/rails_mini_profiler/render_partial_trace.rb +0 -37
- data/app/models/rails_mini_profiler/render_template_trace.rb +0 -37
- data/app/models/rails_mini_profiler/rmp_trace.rb +0 -35
- data/app/models/rails_mini_profiler/sequel_trace.rb +0 -37
@@ -15,21 +15,14 @@ module RailsMiniProfiler
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def created_at
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
inline_svg('graph.svg')
|
27
|
-
end
|
28
|
-
else
|
29
|
-
link_to(flamegraph_path(model.id), title: 'No Flamegraph present for this request', class: 'link-disabled') do
|
30
|
-
inline_svg('graph.svg')
|
31
|
-
end
|
32
|
-
end
|
18
|
+
from_time = Time.now
|
19
|
+
created_at = model.created_at.in_time_zone(Time.zone)
|
20
|
+
distance = if from_time - created_at < 5.minutes
|
21
|
+
'Now'
|
22
|
+
else
|
23
|
+
"#{distance_of_time_in_words(from_time, created_at)} ago"
|
24
|
+
end
|
25
|
+
time_tag(created_at) { content_tag('span', distance) }
|
33
26
|
end
|
34
27
|
|
35
28
|
def flamegraph_button
|
@@ -37,8 +30,8 @@ module RailsMiniProfiler
|
|
37
30
|
|
38
31
|
return nil unless model.flamegraph.present?
|
39
32
|
|
40
|
-
link_to(flamegraph_path(model.id), title: 'Show Flamegraph'
|
41
|
-
content_tag('button', 'Flamegraph')
|
33
|
+
link_to(flamegraph_path(model.id), title: 'Show Flamegraph') do
|
34
|
+
content_tag('button', 'Flamegraph', class: 'btn-grey')
|
42
35
|
end
|
43
36
|
end
|
44
37
|
end
|
@@ -2,10 +2,14 @@
|
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
4
|
class RenderPartialTracePresenter < TracePresenter
|
5
|
+
def identifier
|
6
|
+
payload['identifier']
|
7
|
+
end
|
8
|
+
|
5
9
|
def label
|
6
10
|
root = Rails.root.to_s.split('/').to_set
|
7
|
-
|
8
|
-
(root ^
|
11
|
+
id = identifier.split('/').to_set
|
12
|
+
(root ^ id).drop(2).join('/').reverse.truncate(30).reverse
|
9
13
|
end
|
10
14
|
end
|
11
15
|
end
|
@@ -2,10 +2,14 @@
|
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
4
|
class RenderTemplateTracePresenter < TracePresenter
|
5
|
+
def identifier
|
6
|
+
payload['identifier']
|
7
|
+
end
|
8
|
+
|
5
9
|
def label
|
6
10
|
root = Rails.root.to_s.split('/').to_set
|
7
|
-
|
8
|
-
(root ^
|
11
|
+
id = identifier.split('/').to_set
|
12
|
+
(root ^ id).drop(2).join('/').reverse.truncate(30).reverse
|
9
13
|
end
|
10
14
|
|
11
15
|
def description
|
@@ -6,14 +6,26 @@ module RailsMiniProfiler
|
|
6
6
|
sql_description
|
7
7
|
end
|
8
8
|
|
9
|
+
def name
|
10
|
+
payload['name']
|
11
|
+
end
|
12
|
+
|
13
|
+
def sql
|
14
|
+
payload['sql']
|
15
|
+
end
|
16
|
+
|
17
|
+
def binds
|
18
|
+
payload['binds']
|
19
|
+
end
|
20
|
+
|
9
21
|
alias description label
|
10
22
|
|
11
|
-
def
|
23
|
+
def content
|
12
24
|
return nil if transaction?
|
13
25
|
|
14
26
|
content_tag('div') do
|
15
27
|
content_tag('pre', class: 'trace-payload') do
|
16
|
-
content_tag(:div,
|
28
|
+
content_tag(:div, sql, class: 'sequel-trace-query')
|
17
29
|
end + binding_content
|
18
30
|
end
|
19
31
|
end
|
@@ -57,9 +69,9 @@ module RailsMiniProfiler
|
|
57
69
|
end
|
58
70
|
|
59
71
|
def simple_binds
|
60
|
-
return [] if
|
72
|
+
return [] if binds.nil? || binds.empty?
|
61
73
|
|
62
|
-
|
74
|
+
binds.each_with_object({}) do |hash, object|
|
63
75
|
name = hash['name']
|
64
76
|
value = hash['value']
|
65
77
|
object[name] = value
|
@@ -2,9 +2,12 @@
|
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
4
|
class TracePresenter < BasePresenter
|
5
|
-
def initialize(trace, view,
|
5
|
+
def initialize(trace, view, context: {})
|
6
6
|
super(trace, view)
|
7
|
-
@
|
7
|
+
@start = context[:start]
|
8
|
+
@finish = context[:finish]
|
9
|
+
@total_duration = context[:total_duration]
|
10
|
+
@total_allocations = context[:total_allocations]
|
8
11
|
end
|
9
12
|
|
10
13
|
def label
|
@@ -15,7 +18,7 @@ module RailsMiniProfiler
|
|
15
18
|
label
|
16
19
|
end
|
17
20
|
|
18
|
-
def
|
21
|
+
def content
|
19
22
|
nil
|
20
23
|
end
|
21
24
|
|
@@ -38,7 +41,7 @@ module RailsMiniProfiler
|
|
38
41
|
end
|
39
42
|
|
40
43
|
def duration_percent
|
41
|
-
(model.duration.to_f / @
|
44
|
+
(model.duration.to_f / @total_duration * 100).round
|
42
45
|
end
|
43
46
|
|
44
47
|
def allocations
|
@@ -46,16 +49,15 @@ module RailsMiniProfiler
|
|
46
49
|
end
|
47
50
|
|
48
51
|
def allocations_percent
|
49
|
-
(model.allocations.to_f / @
|
52
|
+
(model.allocations.to_f / @total_allocations * 100).round
|
50
53
|
end
|
51
54
|
|
52
55
|
def from_start
|
53
|
-
(model.start - @
|
56
|
+
(model.start - @start).to_f / 100
|
54
57
|
end
|
55
58
|
|
56
59
|
def from_start_percent
|
57
|
-
((model.start - @
|
58
|
-
(@profiled_request.finish - @profiled_request.start)).to_f * 100
|
60
|
+
((model.start - @start).to_f / (@finish - @start)).to_f * 100
|
59
61
|
end
|
60
62
|
end
|
61
63
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMiniProfiler
|
4
|
+
class BaseSearch
|
5
|
+
def initialize(params = nil, **kwargs)
|
6
|
+
config = self.class.config
|
7
|
+
options = params&.to_h || {}
|
8
|
+
options = options.merge(kwargs)
|
9
|
+
@scope = options.delete(:scope) || (config[:scope] && instance_eval(&config[:scope]))
|
10
|
+
@options = (options.delete(:options) || config[:options]).stringify_keys
|
11
|
+
@params = options.stringify_keys.slice(*@options.keys)
|
12
|
+
end
|
13
|
+
|
14
|
+
def results
|
15
|
+
@results ||= apply
|
16
|
+
end
|
17
|
+
|
18
|
+
def results?
|
19
|
+
results.any?
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def scope(&block)
|
24
|
+
config[:scope] = block
|
25
|
+
end
|
26
|
+
|
27
|
+
def option(name, options = {}, &block)
|
28
|
+
name = name.to_s
|
29
|
+
handler = options[:with] || block
|
30
|
+
|
31
|
+
config[:options][name] = normalize_search_handler(handler, name)
|
32
|
+
|
33
|
+
define_method(name) { @search.param name }
|
34
|
+
end
|
35
|
+
|
36
|
+
def results(**kwargs)
|
37
|
+
new(**kwargs).results
|
38
|
+
end
|
39
|
+
|
40
|
+
def config
|
41
|
+
@config ||= { options: {} }
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def normalize_search_handler(handler, name)
|
47
|
+
case handler
|
48
|
+
when Symbol
|
49
|
+
->(scope, value) { method(handler).call scope, value }
|
50
|
+
when Proc
|
51
|
+
handler
|
52
|
+
else
|
53
|
+
->(scope, value) { scope.where name => value unless value.blank? }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def apply
|
61
|
+
@params.inject(@scope) do |scope, (name, value)|
|
62
|
+
new_scope = instance_exec scope, value, &@options[name]
|
63
|
+
new_scope || scope
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMiniProfiler
|
4
|
+
class ProfiledRequestSearch < BaseSearch
|
5
|
+
option(:id) do |scope, value|
|
6
|
+
scope.where(id: value)
|
7
|
+
end
|
8
|
+
|
9
|
+
option(:path) do |scope, value|
|
10
|
+
scope.where('request_path LIKE ?', "%#{value}%")
|
11
|
+
end
|
12
|
+
|
13
|
+
option(:method) do |scope, value|
|
14
|
+
scope.where(request_method: value)
|
15
|
+
end
|
16
|
+
|
17
|
+
option(:media_type) do |scope, value|
|
18
|
+
scope.where(response_media_type: value)
|
19
|
+
end
|
20
|
+
|
21
|
+
option(:status) do |scope, value|
|
22
|
+
value = value.map(&:to_i)
|
23
|
+
min = value.min
|
24
|
+
max = value.max + 100
|
25
|
+
scope.where('response_status >= :lower', lower: min)
|
26
|
+
.where('response_status < :upper', upper: max)
|
27
|
+
end
|
28
|
+
|
29
|
+
option(:duration) do |scope, value|
|
30
|
+
scope.where('duration > :duration', duration: value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMiniProfiler
|
4
|
+
class TraceSearch < BaseSearch
|
5
|
+
option(:name) do |scope, value|
|
6
|
+
scope.where(name: value)
|
7
|
+
end
|
8
|
+
|
9
|
+
option(:duration) do |scope, value|
|
10
|
+
scope.where('duration > :duration', duration: value)
|
11
|
+
end
|
12
|
+
|
13
|
+
option(:allocations) do |scope, value|
|
14
|
+
scope.where('allocations > :allocations', allocations: value)
|
15
|
+
end
|
16
|
+
|
17
|
+
option(:payload) do |scope, value|
|
18
|
+
payload_column = DatabaseAdapter.cast_to_text(:payload)
|
19
|
+
scope.where("#{payload_column} LIKE ?", "%#{value}%")
|
20
|
+
end
|
21
|
+
|
22
|
+
option(:backtrace) do |scope, value|
|
23
|
+
backtrace_column = Adapters::DatabaseAdapter.cast_to_text(:backtrace)
|
24
|
+
scope.where("#{backtrace_column} LIKE ?", "%#{value}%")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -25,13 +25,13 @@
|
|
25
25
|
transition: opacity 0.3s;
|
26
26
|
}
|
27
27
|
|
28
|
-
#
|
28
|
+
#logo-variant {
|
29
29
|
height: 18px;
|
30
30
|
width: 18px;
|
31
31
|
padding-bottom: 2px;
|
32
32
|
}
|
33
33
|
</style>
|
34
34
|
<a id="rails-mini-profiler-badge" href="<%= profiled_request_path(@profiled_request.id) %>" data-turbolinks="false" title="View performance data">
|
35
|
-
<%= inline_svg('logo_variant.svg'
|
35
|
+
<%= inline_svg('logo_variant.svg') %>
|
36
36
|
<%= (@profiled_request.duration.to_f / 100).round %>ms
|
37
37
|
</a>
|
@@ -1,59 +1,9 @@
|
|
1
|
-
<% if @profiled_requests.empty? %>
|
2
|
-
<section class="placeholder">
|
3
|
-
<%= inline_svg('logo_variant.svg', class: 'placeholder-image') %>
|
4
|
-
<div class="placeholder-text">
|
5
|
-
<h2> There is nothing here yet! </h2>
|
6
|
-
<p>Send some requests to your app for them to show up here</p>
|
7
|
-
</div>
|
8
|
-
</section>
|
9
|
-
<% else %>
|
10
|
-
<h1>Profiled Requests</h1>
|
11
|
-
<div class="profiled-requests-actions">
|
12
|
-
<%= form_with id: 'profiled-request-search-form', url: profiled_requests_url, method: :get do |form| %>
|
13
|
-
<%= form.search_field :path, id: 'profiled-request-search', placeholder: 'Search Path...', class: 'search-field' %>
|
14
|
-
<% end %>
|
15
|
-
<%= link_to(destroy_all_profiled_requests_url,
|
16
|
-
method: :delete,
|
17
|
-
class: 'clear-action',
|
18
|
-
data: { confirm: "This will delete all requests. Are you sure?" }) do %>
|
19
|
-
<button>Clear Requests</button>
|
20
|
-
<% end %>
|
21
|
-
</div>
|
22
|
-
<table id="profiled-requests-table" class="table">
|
23
|
-
<thead>
|
24
|
-
<tr>
|
25
|
-
<th class="text-left">Path</th>
|
26
|
-
<th class="text-left">Method</th>
|
27
|
-
<th class="text-left">Status</th>
|
28
|
-
<th class="text-left">Media Type</th>
|
29
|
-
<th class="text-right">Duration</th>
|
30
|
-
<th class="text-left"></th>
|
31
|
-
<th class="text-left"></th>
|
32
|
-
</tr>
|
33
|
-
</thead>
|
34
1
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
<td class=""><%= profiled_request.created_at %></td>
|
44
|
-
<td class="request-buttons">
|
45
|
-
<%= link_to(profiled_request_path(profiled_request.id), title: 'Show Details') do %>
|
46
|
-
<%= inline_svg('show.svg', options = {}) %>
|
47
|
-
<% end %>
|
48
|
-
<%= profiled_request.flamegraph_icon %>
|
49
|
-
<%= link_to(profiled_request_path(profiled_request.id), title: 'Delete Request', method: :delete) do %>
|
50
|
-
<%= inline_svg('delete.svg') %>
|
51
|
-
<% end %>
|
52
|
-
</td>
|
53
|
-
</tr>
|
54
|
-
<% end %>
|
55
|
-
</tbody>
|
56
|
-
</table>
|
57
|
-
<%== pagy_nav(@pagy) %>
|
58
|
-
<br>
|
59
|
-
<% end %>
|
2
|
+
<div
|
3
|
+
data-controller="filters selectable"
|
4
|
+
data-action="search-controller:submit@window->filters#apply">
|
5
|
+
<%= render "rails_mini_profiler/profiled_requests/shared/header/header" %>
|
6
|
+
<%= render "rails_mini_profiler/profiled_requests/shared/table/table" %>
|
7
|
+
</div>
|
8
|
+
<%== pagy_nav(@pagy) if @pagy.pages > 1 %>
|
9
|
+
<br>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div class="page-header profiled-requests-header">
|
2
|
+
<div class="">
|
3
|
+
<h1>Profiled Requests</h1>
|
4
|
+
</div>
|
5
|
+
<div>
|
6
|
+
<%= button_tag('Delete Selected',
|
7
|
+
disabled: params[:id].blank?,
|
8
|
+
data: {
|
9
|
+
controller: 'enable',
|
10
|
+
'enable-target': 'enable',
|
11
|
+
action: 'rmp:select:change@window->enable#change click->filters#post'
|
12
|
+
}) -%>
|
13
|
+
<%= link_to(destroy_all_profiled_requests_url,
|
14
|
+
method: :delete,
|
15
|
+
data: { confirm: "This will delete all requests. Are you sure?" }) do %>
|
16
|
+
<%= button_tag('Delete All', class: 'btn-red') %>
|
17
|
+
<% end %>
|
18
|
+
</div>
|
19
|
+
</div>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<tr class="no-row">
|
2
|
+
<td colspan="100%">
|
3
|
+
<div class="placeholder">
|
4
|
+
<%= inline_svg('logo_variant.svg', class: 'placeholder-image') %>
|
5
|
+
<div class="placeholder-text">
|
6
|
+
<h2>No Requests found!</h2>
|
7
|
+
<p>Send some requests to your app or modify your filters</p>
|
8
|
+
</div>
|
9
|
+
<%= link_to('Clear Filters', profiled_requests_path, class: 'placeholder-link') %>
|
10
|
+
</div>
|
11
|
+
</td>
|
12
|
+
</tr>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<table
|
2
|
+
id="profiled-requests-table"
|
3
|
+
class="table">
|
4
|
+
<%= render "rails_mini_profiler/profiled_requests/shared/table/table_head" %>
|
5
|
+
<tbody>
|
6
|
+
<% if @profiled_requests.empty? %>
|
7
|
+
<%= render "rails_mini_profiler/profiled_requests/shared/table/placeholder" %>
|
8
|
+
<% else %>
|
9
|
+
<% @profiled_requests.each do |profiled_request| %>
|
10
|
+
<%= render "rails_mini_profiler/profiled_requests/shared/table/table_row", profiled_request: profiled_request %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
13
|
+
</tbody>
|
14
|
+
</table>
|
@@ -0,0 +1,125 @@
|
|
1
|
+
<thead>
|
2
|
+
<tr>
|
3
|
+
<th style="width: 20px;" class="text-left">
|
4
|
+
<%= label_tag nil do %>
|
5
|
+
<%= check_box_tag 'selected[]', nil,
|
6
|
+
params.fetch(:selected, []).size == @pagy.items,
|
7
|
+
class: "request-checkbox",
|
8
|
+
data: {
|
9
|
+
action: 'click->selectable#selectAll',
|
10
|
+
'selectable-target': 'all'
|
11
|
+
}
|
12
|
+
%>
|
13
|
+
<% end %>
|
14
|
+
</th>
|
15
|
+
<th style="width: 25%;" class="text-left" data-controller="dropdown">
|
16
|
+
<button data-action="click->dropdown#toggle click@window->dropdown#hide" data-dropdown-target="button" class="dropdown-toggle none">
|
17
|
+
Path <%= inline_svg('search.svg', class: 'table-filter-icon') %> </button>
|
18
|
+
<div data-controller="search" data-dropdown-target="menu" class="dropdown-container hidden">
|
19
|
+
<div class="dropdown-body">
|
20
|
+
<%= form_with url: profiled_requests_url, method: :get do |form| %>
|
21
|
+
<%= form.search_field :path,
|
22
|
+
value: params[:path],
|
23
|
+
placeholder: 'Search Path',
|
24
|
+
class: 'dropdown-search-field',
|
25
|
+
data: { 'filters-target': 'filter' } %>
|
26
|
+
<%= form.submit 'Search', class: 'btn-red', data: { action: 'click->search#submit' } -%>
|
27
|
+
<% end %>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
</th>
|
31
|
+
<th style="width: 10%;" class="" data-controller="dropdown">
|
32
|
+
<button data-action="click->dropdown#toggle click@window->dropdown#hide" data-dropdown-target="button" class="dropdown-toggle none">
|
33
|
+
Method <%= inline_svg('filter.svg', class: 'table-filter-icon') %> </button>
|
34
|
+
<div data-controller="checklist" data-dropdown-target="menu" class="dropdown-container hidden">
|
35
|
+
<div class="dropdown-header">
|
36
|
+
Select Method...
|
37
|
+
<button class="clear-filters" data-action="checklist#checkNone">
|
38
|
+
Clear filter
|
39
|
+
</button>
|
40
|
+
</div>
|
41
|
+
<% %w[get put post delete].map(&:upcase).each do |method| %>
|
42
|
+
<%= label_tag nil, class: "dropdown-entry" do %>
|
43
|
+
<%= check_box_tag 'method[]', method, params.fetch(:method, []).include?(method),
|
44
|
+
class: "",
|
45
|
+
data: { 'filters-target': "filter" } %>
|
46
|
+
<%= method %>
|
47
|
+
<% end %>
|
48
|
+
<% end %>
|
49
|
+
<button class="dropdown-footer" data-action="filters#apply">
|
50
|
+
Apply
|
51
|
+
</button>
|
52
|
+
</div>
|
53
|
+
</th>
|
54
|
+
<th style="width: 10%;" class="" data-controller="dropdown">
|
55
|
+
<button data-action="click->dropdown#toggle click@window->dropdown#hide" data-dropdown-target="button" class="dropdown-toggle none">
|
56
|
+
Status <%= inline_svg('filter.svg', class: 'table-filter-icon') %> </button>
|
57
|
+
<div data-controller="checklist" data-dropdown-target="menu" class="dropdown-container hidden">
|
58
|
+
<div class="dropdown-header">
|
59
|
+
Select Status...
|
60
|
+
<button class="clear-filters" data-action="checklist#checkNone filters#apply">
|
61
|
+
Clear filter
|
62
|
+
</button>
|
63
|
+
</div>
|
64
|
+
<% %w[200 300 400 500].each do |status| %>
|
65
|
+
<%= label_tag nil, class: "dropdown-entry" do %>
|
66
|
+
<%= check_box_tag 'status[]', status, params.fetch(:status, []).include?(status),
|
67
|
+
class: "",
|
68
|
+
data: { 'filters-target': "filter" } %>
|
69
|
+
<%= status %>
|
70
|
+
<% end %>
|
71
|
+
<% end %>
|
72
|
+
<button class="dropdown-footer" data-action="filters#apply">
|
73
|
+
Apply
|
74
|
+
</button>
|
75
|
+
</div>
|
76
|
+
</th>
|
77
|
+
<th style="width: 15%;" class="" data-controller="dropdown">
|
78
|
+
<button data-action="click->dropdown#toggle click@window->dropdown#hide" data-dropdown-target="button" class="dropdown-toggle none">
|
79
|
+
Media Type <%= inline_svg('filter.svg', class: 'table-filter-icon') %> </button>
|
80
|
+
<div data-controller="checklist" data-dropdown-target="menu" class="dropdown-container hidden">
|
81
|
+
<div class="dropdown-header">
|
82
|
+
Select Media Type...
|
83
|
+
<button class="clear-filters" data-action="checklist#checkNone filters#apply">
|
84
|
+
Clear filter
|
85
|
+
</button>
|
86
|
+
</div>
|
87
|
+
<% %w[text/html application/json application/xml].each do |media_type| %>
|
88
|
+
<%= label_tag nil, class: "dropdown-entry" do %>
|
89
|
+
<%= check_box_tag 'media_type[]', media_type, params.fetch(:media_type, []).include?(media_type),
|
90
|
+
class: "",
|
91
|
+
data: { target: "filters.filter" } %>
|
92
|
+
<%= media_type %>
|
93
|
+
<% end %>
|
94
|
+
<% end %>
|
95
|
+
<button class="dropdown-footer" data-action="filters#apply">
|
96
|
+
Apply
|
97
|
+
</button>
|
98
|
+
</div>
|
99
|
+
</th>
|
100
|
+
<th style="width: 10%;" class="text-left" data-controller="dropdown">
|
101
|
+
<button data-action="click->dropdown#toggle click@window->dropdown#hide" data-dropdown-target="button" class="dropdown-toggle none">
|
102
|
+
Duration <%= inline_svg('filter.svg', class: 'table-filter-icon') %> </button>
|
103
|
+
<div data-controller="checklist" data-dropdown-target="menu" class="dropdown-container hidden">
|
104
|
+
<div class="dropdown-header">
|
105
|
+
Select Duration...
|
106
|
+
<button class="clear-filters" data-action="checklist#checkNone filters#apply">
|
107
|
+
Clear filter
|
108
|
+
</button>
|
109
|
+
</div>
|
110
|
+
<% [100_00, 250_00, 500_00].each do |duration| %>
|
111
|
+
<%= label_tag nil, class: "dropdown-entry" do %>
|
112
|
+
<%= radio_button_tag 'duration', duration.to_s , params.fetch(:duration, []).include?(duration.to_s),
|
113
|
+
class: "",
|
114
|
+
data: { target: "filters.filter" } %>
|
115
|
+
<%= "> #{duration / 100}ms" %>
|
116
|
+
<% end %>
|
117
|
+
<% end %>
|
118
|
+
<button class="dropdown-footer" data-action="filters#apply">
|
119
|
+
Apply
|
120
|
+
</button>
|
121
|
+
</div>
|
122
|
+
</th>
|
123
|
+
<th style="width: 15%;" class="text-left">Date</th>
|
124
|
+
</tr>
|
125
|
+
</thead>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<tr data-link="<%= profiled_request_path(profiled_request.id) %>">
|
2
|
+
<td class="">
|
3
|
+
<%= label_tag nil do %>
|
4
|
+
<%= check_box_tag 'id[]', profiled_request.id,
|
5
|
+
params.fetch(:selected, []).include?(profiled_request.id),
|
6
|
+
class: "request-checkbox",
|
7
|
+
data: {
|
8
|
+
'selectable-target': 'selectable',
|
9
|
+
'filters-target': 'filter',
|
10
|
+
action: 'click->selectable#onSelected'
|
11
|
+
},
|
12
|
+
onclick: "event.stopPropagation();" %>
|
13
|
+
<% end %>
|
14
|
+
</td>
|
15
|
+
<td class="request-path"><%= profiled_request.request_name %></td>
|
16
|
+
<td class="text-left"> <%= profiled_request.request_method %> </td>
|
17
|
+
<td class="text-left"> <%= profiled_request.response_status %> </td>
|
18
|
+
<td class="text-left"> <%= profiled_request.response_media_type %> </td>
|
19
|
+
<td class="text-left"><%= profiled_request.duration %> ms</td>
|
20
|
+
<td class="text-left"><%= profiled_request.created_at %></td>
|
21
|
+
</tr>
|
@@ -7,8 +7,29 @@
|
|
7
7
|
<button class="popover-close">x</button>
|
8
8
|
</section>
|
9
9
|
<section class="popover-body">
|
10
|
-
<%= trace.
|
11
|
-
|
10
|
+
<%= trace.content %>
|
11
|
+
|
12
|
+
<% if trace.backtrace %>
|
13
|
+
<section class="popover-footer">
|
14
|
+
<div
|
15
|
+
class="backtrace"
|
16
|
+
data-controller="clipboard"
|
17
|
+
data-clipboard-filter=".+?(?=:in)"
|
18
|
+
data-clipboard-copied-message="Copied" >
|
19
|
+
<pre data-clipboard-target="source"><%= trace.backtrace %></pre>
|
20
|
+
<button
|
21
|
+
title="Copy to clipboard"
|
22
|
+
type="button"
|
23
|
+
data-action="clipboard#copy"
|
24
|
+
data-clipboard-target="button"
|
25
|
+
>
|
26
|
+
<%= inline_svg('copy.svg') %>
|
27
|
+
</button>
|
28
|
+
</div>
|
29
|
+
</section>
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
<table class="trace-details-table">
|
12
33
|
<thead>
|
13
34
|
<tr>
|
14
35
|
<th class="text-left"></th>
|
@@ -30,11 +51,7 @@
|
|
30
51
|
</table>
|
31
52
|
</section>
|
32
53
|
|
33
|
-
|
34
|
-
<section class="popover-footer">
|
35
|
-
<pre><%= trace.backtrace %></pre>
|
36
|
-
</section>
|
37
|
-
<% end %>
|
54
|
+
|
38
55
|
</div>
|
39
56
|
</div>
|
40
57
|
</li>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<section class="trace-list">
|
2
|
+
<%= render "rails_mini_profiler/profiled_requests/show/trace_list_header" %>
|
3
|
+
<% if @traces.empty? %>
|
4
|
+
<%= render "rails_mini_profiler/profiled_requests/show/trace_list_placeholder" %>
|
5
|
+
<% else %>
|
6
|
+
<ol>
|
7
|
+
<% @traces.each do |trace| %>
|
8
|
+
<%= render "rails_mini_profiler/profiled_requests/show/trace", trace: trace %>
|
9
|
+
<% end %>
|
10
|
+
</ol>
|
11
|
+
<% end %>
|
12
|
+
</section>
|