Optimize imports, fix up tracking records and time overall
This commit is contained in:
@@ -44,17 +44,44 @@ interface HistoryRecord {
|
||||
interface ImportHistoryRecord extends HistoryRecord {
|
||||
records_added: number;
|
||||
records_updated: number;
|
||||
records_deleted?: number;
|
||||
records_skipped?: number;
|
||||
is_incremental?: boolean;
|
||||
total_processed?: number;
|
||||
additional_info?: {
|
||||
step_timings?: Record<string, number>;
|
||||
details?: {
|
||||
categories?: { recordsAdded: number; recordsUpdated: number; skippedCategories?: number };
|
||||
products?: { totalProcessed: number; needsUpdate: number; skippedUnchanged?: number };
|
||||
orders?: { totalProcessed: number; totalSkipped: number; missingProducts: number };
|
||||
purchaseOrders?: { recordsAdded: number; recordsUpdated: number; recordsDeleted: number; skippedProducts: number };
|
||||
};
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
interface CalculateHistoryRecord extends HistoryRecord {
|
||||
total_products: number;
|
||||
total_orders: number;
|
||||
total_purchase_orders: number;
|
||||
processed_products: number;
|
||||
processed_orders: number;
|
||||
processed_purchase_orders: number;
|
||||
total_products?: number;
|
||||
total_orders?: number;
|
||||
total_purchase_orders?: number;
|
||||
processed_products?: number;
|
||||
processed_orders?: number;
|
||||
processed_purchase_orders?: number;
|
||||
duration_minutes?: number;
|
||||
duration_seconds?: number;
|
||||
additional_info?: {
|
||||
type?: string;
|
||||
steps?: string[];
|
||||
completed_steps?: Array<{
|
||||
name: string;
|
||||
duration: number;
|
||||
status: string;
|
||||
rowsAffected?: number;
|
||||
}>;
|
||||
step_timings?: Record<string, number>;
|
||||
step_row_counts?: Record<string, number>;
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
interface ModuleStatus {
|
||||
@@ -369,6 +396,82 @@ export function DataManagement() {
|
||||
const formatJsonData = (data: Record<string, any>) => {
|
||||
if (!data) return null;
|
||||
|
||||
// Special handling for completed_steps
|
||||
if (data.completed_steps && Array.isArray(data.completed_steps)) {
|
||||
return (
|
||||
<div className="space-y-2 mt-2">
|
||||
<div className="text-sm font-semibold text-gray-700">Completed Steps:</div>
|
||||
<div className="space-y-1 bg-gray-50 p-2 rounded">
|
||||
{data.completed_steps.map((step: any, idx: number) => (
|
||||
<div key={idx} className="flex justify-between text-sm">
|
||||
<span className="font-medium">{step.name}</span>
|
||||
<div className="flex gap-4 text-gray-600">
|
||||
<span>{step.duration}s</span>
|
||||
{step.rowsAffected !== undefined && (
|
||||
<span>{formatNumber(step.rowsAffected)} rows</span>
|
||||
)}
|
||||
<span className={step.status === 'completed' ? 'text-green-600' : 'text-red-600'}>
|
||||
{step.status}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Show other data if present */}
|
||||
{Object.keys(data).filter(k => k !== 'completed_steps').length > 0 && (
|
||||
<div className="mt-2">
|
||||
{formatJsonDataSimple(Object.fromEntries(
|
||||
Object.entries(data).filter(([k]) => k !== 'completed_steps')
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Special handling for import details
|
||||
if (data.details) {
|
||||
return (
|
||||
<div className="space-y-2 mt-2">
|
||||
<div className="text-sm font-semibold text-gray-700">Import Details:</div>
|
||||
<div className="space-y-2 bg-gray-50 p-2 rounded">
|
||||
{Object.entries(data.details).map(([table, stats]: [string, any]) => (
|
||||
<div key={table} className="border-b last:border-0 pb-2 last:pb-0">
|
||||
<div className="font-medium text-sm capitalize mb-1">{table}:</div>
|
||||
<div className="grid grid-cols-2 gap-x-4 gap-y-1 text-xs">
|
||||
{Object.entries(stats).map(([key, value]) => (
|
||||
<div key={key} className="flex justify-between">
|
||||
<span className="text-gray-600">{key}:</span>
|
||||
<span className="font-mono">{typeof value === 'number' ? formatNumber(value) : String(value)}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Show step timings if present */}
|
||||
{data.step_timings && (
|
||||
<div className="mt-2">
|
||||
<div className="text-sm font-semibold text-gray-700">Step Timings:</div>
|
||||
<div className="space-y-1 bg-gray-50 p-2 rounded text-sm">
|
||||
{Object.entries(data.step_timings).map(([step, duration]) => (
|
||||
<div key={step} className="flex justify-between">
|
||||
<span className="text-gray-600">{step}:</span>
|
||||
<span className="font-mono">{String(duration)}s</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Default simple format
|
||||
return formatJsonDataSimple(data);
|
||||
};
|
||||
|
||||
const formatJsonDataSimple = (data: Record<string, any>) => {
|
||||
// Find the longest key length
|
||||
const maxKeyLength = Object.keys(data).reduce(
|
||||
(max, key) => Math.max(max, key.length),
|
||||
@@ -384,13 +487,13 @@ export function DataManagement() {
|
||||
style={{ width: `${maxKeyLength + 2}ch` }}
|
||||
>
|
||||
{key}:
|
||||
</span>
|
||||
</span>
|
||||
<span className="break-all">
|
||||
{typeof value === "object"
|
||||
? JSON.stringify(value)
|
||||
: value?.toString()}
|
||||
</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
@@ -1133,12 +1236,33 @@ export function DataManagement() {
|
||||
: "N/A"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-600">Records:</span>
|
||||
<span>
|
||||
{record.records_added} added,{" "}
|
||||
{record.records_updated} updated
|
||||
</span>
|
||||
<div className="grid grid-cols-2 gap-2 text-sm">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">Added:</span>
|
||||
<span className="text-green-600 font-medium">{formatNumber(record.records_added)}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">Updated:</span>
|
||||
<span className="text-blue-600 font-medium">{formatNumber(record.records_updated)}</span>
|
||||
</div>
|
||||
{record.records_deleted !== undefined && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">Deleted:</span>
|
||||
<span className="text-red-600 font-medium">{formatNumber(record.records_deleted)}</span>
|
||||
</div>
|
||||
)}
|
||||
{record.records_skipped !== undefined && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">Skipped:</span>
|
||||
<span className="text-yellow-600 font-medium">{formatNumber(record.records_skipped)}</span>
|
||||
</div>
|
||||
)}
|
||||
{record.total_processed !== undefined && (
|
||||
<div className="flex justify-between col-span-2">
|
||||
<span className="text-gray-600">Total Processed:</span>
|
||||
<span className="font-medium">{formatNumber(record.total_processed)}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{record.error_message && (
|
||||
<div className="text-sm text-red-600 mt-2">
|
||||
|
||||
Reference in New Issue
Block a user