Files
baffle-hub/app/views/data_imports/show.html.erb
2025-11-11 16:54:52 +11:00

224 lines
9.5 KiB
Plaintext

<%# Helper methods %>
<% def status_badge(status) %>
<% case status %>
<% when 'pending' %>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
<%= status.capitalize %>
</span>
<% when 'processing' %>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
<%= status.capitalize %>
</span>
<% when 'completed' %>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
<%= status.capitalize %>
</span>
<% when 'failed' %>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
<%= status.capitalize %>
</span>
<% else %>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
<%= status.capitalize %>
</span>
<% end %>
<% end %>
<div class="max-w-4xl mx-auto">
<!-- Header -->
<div class="bg-white shadow-sm rounded-lg mb-6">
<div class="px-6 py-4 border-b border-gray-200">
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-semibold text-gray-900">Import Details</h1>
<p class="mt-1 text-sm text-gray-600">
<%= @data_import.filename %>
</p>
</div>
<div class="flex items-center space-x-2">
<%= link_to "← Back to Imports", data_imports_path, class: "inline-flex items-center px-3 py-2 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500" %>
<% unless @data_import.processing? %>
<%= link_to "Delete", @data_import,
data: {
turbo_method: :delete,
turbo_confirm: "Are you sure you want to delete this import record?"
},
class: "inline-flex items-center px-3 py-2 border border-red-300 shadow-sm text-sm leading-4 font-medium rounded-md text-red-700 bg-white hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500" %>
<% end %>
</div>
</div>
</div>
</div>
<!-- Progress Card -->
<div data-controller="data-import-progress"
data-data-import-progress-import-id-value="<%= @data_import.id %>"
class="bg-white shadow-sm rounded-lg mb-6">
<div class="px-6 py-4">
<div class="flex items-center justify-between mb-4">
<h2 class="text-lg font-medium text-gray-900">Import Progress</h2>
<%= status_badge(@data_import.status) %>
</div>
<!-- Progress Bar -->
<div class="mb-4">
<div class="flex items-center justify-between text-sm text-gray-600 mb-1">
<span>
<% if @data_import.total_records > 0 && @data_import.processed_records >= @data_import.total_records %>
<%= number_with_delimiter(@data_import.processed_records) %> total records
<% elsif @data_import.total_records > 0 %>
<%= number_with_delimiter(@data_import.processed_records) %> records processed
<% else %>
Initializing...
<% end %>
</span>
<span><%= @data_import.progress_percentage %>%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div data-data-import-progress-target="progressBar"
class="bg-blue-600 h-2 rounded-full transition-all duration-300"
style="width: <%= @data_import.progress_percentage %>%"></div>
</div>
</div>
<!-- Stats Grid -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
<div class="bg-gray-50 rounded-lg p-4">
<div class="text-2xl font-semibold text-gray-900" data-data-import-progress-target="totalRecords">
<%= number_with_delimiter(@data_import.total_records) %>
</div>
<div class="text-sm text-gray-600">Total Records</div>
</div>
<div class="bg-green-50 rounded-lg p-4">
<div class="text-2xl font-semibold text-green-900" data-data-import-progress-target="processedRecords">
<%= number_with_delimiter(@data_import.processed_records) %>
</div>
<div class="text-sm text-green-600">Processed</div>
</div>
<div class="bg-red-50 rounded-lg p-4">
<div class="text-2xl font-semibold text-red-900" data-data-import-progress-target="failedRecords">
<%= number_with_delimiter(@data_import.failed_records) %>
</div>
<div class="text-sm text-red-600">Failed</div>
</div>
<div class="bg-blue-50 rounded-lg p-4">
<div class="text-2xl font-semibold text-blue-900" data-data-import-progress-target="recordsPerSecond">
<%= number_with_delimiter(@data_import.records_per_second) %>
</div>
<div class="text-sm text-blue-600">Records/Sec</div>
</div>
</div>
</div>
</div>
<!-- Import Details -->
<div class="bg-white shadow-sm rounded-lg mb-6">
<div class="px-6 py-4 border-b border-gray-200">
<h2 class="text-lg font-medium text-gray-900">Import Information</h2>
</div>
<div class="px-6 py-4">
<dl class="grid grid-cols-1 gap-x-4 gap-y-6 sm:grid-cols-2">
<div>
<dt class="text-sm font-medium text-gray-500">Import Type</dt>
<dd class="mt-1 text-sm text-gray-900 capitalize"><%= @data_import.import_type %></dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500">Filename</dt>
<dd class="mt-1 text-sm text-gray-900"><%= @data_import.filename %></dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500">Started</dt>
<dd class="mt-1 text-sm text-gray-900">
<% if @data_import.processing? && @data_import.started_at %>
<%= time_ago_in_words(@data_import.started_at) %> ago
(<%= @data_import.started_at.strftime('%Y-%m-%d %H:%M:%S') %>)
<% elsif @data_import.processing? %>
Initializing...
<% elsif @data_import.started_at %>
<%= time_ago_in_words(@data_import.started_at) %> ago
(<%= @data_import.started_at.strftime('%Y-%m-%d %H:%M:%S') %>)
<% else %>
Not started
<% end %>
</dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500">Duration</dt>
<dd class="mt-1 text-sm text-gray-900">
<% if @data_import.duration > 0 %>
<%= distance_of_time_in_words(@data_import.duration) %>
<% else %>
N/A
<% end %>
</dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500">Completed</dt>
<dd class="mt-1 text-sm text-gray-900">
<% if @data_import.completed? && @data_import.completed_at %>
<%= time_ago_in_words(@data_import.completed_at) %> ago
(<%= @data_import.completed_at.strftime('%Y-%m-%d %H:%M:%S') %>)
<% elsif @data_import.completed? %>
Just now
<% elsif @data_import.processing? %>
In progress...
<% else %>
Not completed
<% end %>
</dd>
</div>
</dl>
</div>
</div>
<!-- Error Details (if any) -->
<% if @data_import.error_message.present? || @data_import.import_stats['errors']&.any? %>
<div class="bg-red-50 border border-red-200 rounded-lg mb-6">
<div class="px-6 py-4 border-b border-red-200">
<h2 class="text-lg font-medium text-red-900">Error Details</h2>
</div>
<div class="px-6 py-4">
<% if @data_import.error_message.present? %>
<div class="mb-4">
<h3 class="text-sm font-medium text-red-800 mb-2">General Error</h3>
<p class="text-sm text-red-700"><%= @data_import.error_message %></p>
</div>
<% end %>
<% if @data_import.import_stats['errors']&.any? %>
<div>
<h3 class="text-sm font-medium text-red-800 mb-2">Recent Errors (<%= @data_import.import_stats['errors'].size %>)</h3>
<div class="bg-white rounded border border-red-200 p-3 max-h-48 overflow-y-auto">
<ul class="space-y-2">
<% @data_import.import_stats['errors'].each do |error| %>
<li class="text-xs text-red-700 font-mono"><%= error %></li>
<% end %>
</ul>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
<!-- Additional Stats (if available) -->
<% if @data_import.import_stats&.any? && (@data_import.import_stats.except('errors', 'completed_at')).any? %>
<div class="bg-white shadow-sm rounded-lg">
<div class="px-6 py-4 border-b border-gray-200">
<h2 class="text-lg font-medium text-gray-900">Additional Statistics</h2>
</div>
<div class="px-6 py-4">
<dl class="grid grid-cols-1 gap-x-4 gap-y-6 sm:grid-cols-2">
<% @data_import.import_stats.except('errors', 'completed_at').each do |key, value| %>
<div>
<dt class="text-sm font-medium text-gray-500"><%= key.to_s.humanize %></dt>
<dd class="mt-1 text-sm text-gray-900"><%= value.is_a?(Hash) ? value.inspect : value %></dd>
</div>
<% end %>
</dl>
</div>
</div>
<% end %>
</div>