Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions app/views/layouts/solid_errors/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,71 @@
document.querySelectorAll('[data-controller="fade"]').forEach(element => {
fadeOut(element);
});

// Backtrace filter toggle functionality
(function() {
const STORAGE_KEY = 'solid_errors_backtrace_filter';

function toggleBacktrace(button) {
const filter = button.getAttribute('data-backtrace-toggle');
const occurrenceId = button.getAttribute('data-occurrence-id');

// Toggle visibility
const appTrace = document.getElementById(`backtrace-application-${occurrenceId}`);
const fullTrace = document.getElementById(`backtrace-full-${occurrenceId}`);

if (filter === 'application') {
appTrace.removeAttribute('hidden');
fullTrace.setAttribute('hidden', '');
} else {
appTrace.setAttribute('hidden', '');
fullTrace.removeAttribute('hidden');
}

// Update button states for this occurrence
const occurrenceButtons = document.querySelectorAll(`[data-occurrence-id="${occurrenceId}"][data-backtrace-toggle]`);
occurrenceButtons.forEach(btn => {
if (btn === button) {
btn.classList.add('border-blue-500', 'text-blue-500');
btn.classList.remove('border-transparent', 'text-gray-500');
} else {
btn.classList.remove('border-blue-500', 'text-blue-500');
btn.classList.add('border-transparent', 'text-gray-500');
}
});

// Save preference
sessionStorage.setItem(STORAGE_KEY, filter);
}

// Initialize on page load
const savedFilter = sessionStorage.getItem(STORAGE_KEY) || 'application';

// Apply saved filter to all occurrences
if (savedFilter === 'full') {
document.querySelectorAll('[id^="backtrace-application-"]').forEach(el => el.setAttribute('hidden', ''));
document.querySelectorAll('[id^="backtrace-full-"]').forEach(el => el.removeAttribute('hidden'));

// Update button states
document.querySelectorAll('[data-backtrace-toggle]').forEach(btn => {
const filter = btn.getAttribute('data-backtrace-toggle');
if (filter === savedFilter) {
btn.classList.add('border-blue-500', 'text-blue-500');
btn.classList.remove('border-transparent', 'text-gray-500');
} else {
btn.classList.remove('border-blue-500', 'text-blue-500');
btn.classList.add('border-transparent', 'text-gray-500');
}
});
}

// Attach event listeners
document.querySelectorAll('[data-backtrace-toggle]').forEach(button => {
button.addEventListener('click', function() {
toggleBacktrace(this);
});
});
})();
</script>
</body>
</html>
73 changes: 59 additions & 14 deletions app/views/solid_errors/occurrences/_occurrence.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,67 @@
<%= SolidErrors::Occurrence.human_attribute_name(:backtrace) %>
</dt>
<dd class="">
<% backtrace.lines.each_with_index do |line, i| %>
<%= tag.details open: line.application? || i.zero? do %>
<summary class="hover:bg-gray-50 px-2 py-1 rounded cursor-pointer">
<% if line.filtered_file %>
<span class="text-gray-500"><%= File.dirname(line.filtered_file) %>/</span><span class="text-blue-500 font-medium"><%= File.basename(line.filtered_file) %></span>:<span class="text-gray-900 font-medium"><%= line.filtered_number %></span>
<span class="text-gray-500">in</span>
<code class="text-green-500 font-medium"><%= line.filtered_method %></code>
<% else %>
<span class="text-gray-500"><%= line.unparsed_line %></span>
<div class="flex gap-2 mb-2 -ml-px">
<button type="button"
data-backtrace-toggle="application"
data-occurrence-id="<%= occurrence.id %>"
class="backtrace-toggle inline-flex items-center border-b-2 px-3 py-2 text-sm font-medium cursor-pointer border-blue-500 text-blue-500">
Application
</button>
<button type="button"
data-backtrace-toggle="full"
data-occurrence-id="<%= occurrence.id %>"
class="backtrace-toggle inline-flex items-center border-b-2 px-3 py-2 text-sm font-medium cursor-pointer border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700">
Full
</button>
</div>

<div id="backtrace-application-<%= occurrence.id %>">
<% if backtrace.application_lines.empty? %>
<p class="text-gray-500 italic text-sm">
No application code in backtrace.
<button type="button" data-backtrace-toggle="full" data-occurrence-id="<%= occurrence.id %>" class="text-blue-500 hover:underline cursor-pointer">
View full trace
</button>
</p>
<% else %>
<% backtrace.application_lines.each_with_index do |line, i| %>
<%= tag.details open: line.application? || i.zero? do %>
<summary class="hover:bg-gray-50 px-2 py-1 rounded cursor-pointer">
<% if line.filtered_file %>
<span class="text-gray-500"><%= File.dirname(line.filtered_file) %>/</span><span class="text-blue-500 font-medium"><%= File.basename(line.filtered_file) %></span>:<span class="text-gray-900 font-medium"><%= line.filtered_number %></span>
<span class="text-gray-500">in</span>
<code class="text-green-500 font-medium"><%= line.filtered_method %></code>
<% else %>
<span class="text-gray-500"><%= line.unparsed_line %></span>
<% end %>
</summary>
<div><pre class="flex overflow-auto rounded-b-lg bg-slate-800 p-4 text-sm leading-normal text-white sm:rounded-t-lg"><code class="flex flex-1 flex-col min-h-full min-w-content px-0"><% line.source.each do |n, code| %>
<div class="line <%= n == line.filtered_number.to_i ? 'bg-gray-600/50' : '' %>"><span class="mr-2 text-right select-none text-gray-600"><%= n %></span><span><%= code %></span></div>
<% end %></code></pre></div>
<% end %>
</summary>
<div><pre class="flex overflow-auto rounded-b-lg bg-slate-800 p-4 text-sm leading-normal text-white sm:rounded-t-lg"><code class="flex flex-1 flex-col min-h-full min-w-content px-0"><% line.source.each do |n, code| %>
<div class="line <%= n == line.filtered_number.to_i ? 'bg-gray-600/50' : '' %>"><span class="mr-2 text-right select-none text-gray-600"><%= n %></span><span><%= code %></span></div>
<% end %></code></pre></div>
<% end %>
<% end %>
</div>

<div id="backtrace-full-<%= occurrence.id %>" hidden>
<% backtrace.lines.each_with_index do |line, i| %>
<%= tag.details open: line.application? || i.zero? do %>
<summary class="hover:bg-gray-50 px-2 py-1 rounded cursor-pointer">
<% if line.filtered_file %>
<span class="text-gray-500"><%= File.dirname(line.filtered_file) %>/</span><span class="text-blue-500 font-medium"><%= File.basename(line.filtered_file) %></span>:<span class="text-gray-900 font-medium"><%= line.filtered_number %></span>
<span class="text-gray-500">in</span>
<code class="text-green-500 font-medium"><%= line.filtered_method %></code>
<% else %>
<span class="text-gray-500"><%= line.unparsed_line %></span>
<% end %>
</summary>
<div><pre class="flex overflow-auto rounded-b-lg bg-slate-800 p-4 text-sm leading-normal text-white sm:rounded-t-lg"><code class="flex flex-1 flex-col min-h-full min-w-content px-0"><% line.source.each do |n, code| %>
<div class="line <%= n == line.filtered_number.to_i ? 'bg-gray-600/50' : '' %>"><span class="mr-2 text-right select-none text-gray-600"><%= n %></span><span><%= code %></span></div>
<% end %></code></pre></div>
<% end %>
<% end %>
<% end %>
</div>
</dd>
</div>
</dl>
Expand Down