Add more tables to db and processing to import script, add error logging to import, add test data snapshots (untested)
This commit is contained in:
@@ -58,6 +58,9 @@ export function Settings() {
|
||||
orders: 0,
|
||||
purchaseOrders: 0
|
||||
});
|
||||
const [isCreatingSnapshot, setIsCreatingSnapshot] = useState(false);
|
||||
const [isRestoringSnapshot, setIsRestoringSnapshot] = useState(false);
|
||||
const [snapshotProgress, setSnapshotProgress] = useState<ImportProgress | null>(null);
|
||||
|
||||
// Helper function to update progress state
|
||||
const updateProgressState = (progressData: any) => {
|
||||
@@ -87,11 +90,15 @@ export function Settings() {
|
||||
setImportProgress(prev => ({ ...prev, ...progressUpdate }));
|
||||
} else if (operation.includes('purchase orders import')) {
|
||||
setPurchaseOrdersProgress(prev => ({ ...prev, ...progressUpdate }));
|
||||
} else if (operation.includes('metrics') || operation.includes('vendor metrics')) {
|
||||
setImportProgress(prev => ({ ...prev, ...progressUpdate }));
|
||||
} else if (operation.includes('snapshot')) {
|
||||
setSnapshotProgress(prev => ({ ...prev, ...progressUpdate }));
|
||||
}
|
||||
};
|
||||
|
||||
// Helper to connect to event source
|
||||
const connectToEventSource = useCallback((type: 'update' | 'import' | 'reset') => {
|
||||
const connectToEventSource = useCallback((type: 'update' | 'import' | 'reset' | 'snapshot') => {
|
||||
if (eventSource) {
|
||||
eventSource.close();
|
||||
}
|
||||
@@ -389,6 +396,63 @@ export function Settings() {
|
||||
}
|
||||
};
|
||||
|
||||
// Add handlers for snapshot operations
|
||||
const handleCreateSnapshot = async () => {
|
||||
try {
|
||||
setIsCreatingSnapshot(true);
|
||||
setSnapshotProgress({ status: 'running', operation: 'Creating test data snapshot' });
|
||||
|
||||
// Connect to SSE for progress updates
|
||||
connectToEventSource('snapshot');
|
||||
|
||||
const response = await fetch(`${config.apiUrl}/snapshot/create`, {
|
||||
method: 'POST',
|
||||
credentials: 'include'
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to create snapshot');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating snapshot:', error);
|
||||
if (eventSource) {
|
||||
eventSource.close();
|
||||
setEventSource(null);
|
||||
}
|
||||
setIsCreatingSnapshot(false);
|
||||
setSnapshotProgress(null);
|
||||
toast.error('Failed to create snapshot');
|
||||
}
|
||||
};
|
||||
|
||||
const handleRestoreSnapshot = async () => {
|
||||
try {
|
||||
setIsRestoringSnapshot(true);
|
||||
setSnapshotProgress({ status: 'running', operation: 'Restoring test data snapshot' });
|
||||
|
||||
// Connect to SSE for progress updates
|
||||
connectToEventSource('snapshot');
|
||||
|
||||
const response = await fetch(`${config.apiUrl}/snapshot/restore`, {
|
||||
method: 'POST',
|
||||
credentials: 'include'
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to restore snapshot');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error restoring snapshot:', error);
|
||||
if (eventSource) {
|
||||
eventSource.close();
|
||||
setEventSource(null);
|
||||
}
|
||||
setIsRestoringSnapshot(false);
|
||||
setSnapshotProgress(null);
|
||||
toast.error('Failed to restore snapshot');
|
||||
}
|
||||
};
|
||||
|
||||
// Cleanup on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
@@ -625,6 +689,30 @@ export function Settings() {
|
||||
{renderProgress(purchaseOrdersProgress)}
|
||||
</div>
|
||||
)}
|
||||
{/* Show metrics calculation progress */}
|
||||
{importProgress?.operation?.toLowerCase().includes('metrics') && (
|
||||
<div>
|
||||
<Progress value={Number(importProgress.percentage)} className="mb-2" />
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{importProgress.message || importProgress.operation || 'Calculating metrics...'}
|
||||
{importProgress.current && importProgress.total && (
|
||||
<> ({importProgress.current} of {importProgress.total})</>
|
||||
)}
|
||||
</p>
|
||||
{importProgress.elapsed && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Elapsed: {importProgress.elapsed}
|
||||
{importProgress.remaining && <> • Remaining: {importProgress.remaining}</>}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{/* Show vendor metrics progress */}
|
||||
{importProgress?.operation?.toLowerCase().includes('vendor metrics') && (
|
||||
<div>
|
||||
{renderProgress(importProgress)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
@@ -637,36 +725,104 @@ export function Settings() {
|
||||
<CardDescription>Drop all tables and recreate the database schema. This will delete ALL data.</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex gap-2">
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="destructive" disabled={isResetting || isImporting || isUpdating}>
|
||||
Reset Database
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This action cannot be undone. This will permanently delete all data from the database.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={handleResetDB}>Continue</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
{resetProgress && (
|
||||
<div className="mt-4">
|
||||
<Progress value={Number(resetProgress.percentage)} className="mb-2" />
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{resetProgress.message || 'Resetting database...'}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Test Data Snapshots Card */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Test Data Snapshots</CardTitle>
|
||||
<CardDescription>Create and restore test data snapshots for development and testing.</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex space-x-4">
|
||||
<Button
|
||||
onClick={handleCreateSnapshot}
|
||||
disabled={isCreatingSnapshot || isRestoringSnapshot || isImporting || isUpdating || isResetting}
|
||||
>
|
||||
{isCreatingSnapshot ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
Creating Snapshot...
|
||||
</>
|
||||
) : (
|
||||
<>Create Snapshot</>
|
||||
)}
|
||||
</Button>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button
|
||||
variant="destructive"
|
||||
className="flex-1"
|
||||
disabled={isUpdating || isImporting}
|
||||
variant="secondary"
|
||||
disabled={isCreatingSnapshot || isRestoringSnapshot || isImporting || isUpdating || isResetting}
|
||||
>
|
||||
Reset Database
|
||||
{isRestoringSnapshot ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
Restoring...
|
||||
</>
|
||||
) : (
|
||||
<>Restore Snapshot</>
|
||||
)}
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||
<AlertDialogTitle>Restore test data snapshot?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This action cannot be undone. This will permanently delete all data
|
||||
from the database and reset it to its initial state.
|
||||
This will replace your current database with the test data snapshot. Any unsaved changes will be lost.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={handleResetDB}>
|
||||
Reset Database
|
||||
</AlertDialogAction>
|
||||
<AlertDialogAction onClick={handleRestoreSnapshot}>Continue</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</div>
|
||||
|
||||
{isResetting && renderProgress(resetProgress)}
|
||||
{snapshotProgress && (
|
||||
<div>
|
||||
<Progress value={Number(snapshotProgress.percentage)} className="mb-2" />
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{snapshotProgress.message || 'Processing snapshot...'}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="text-sm text-muted-foreground">
|
||||
<p>The test data snapshot includes:</p>
|
||||
<ul className="list-disc list-inside mt-2">
|
||||
<li>~100 diverse products with associated data</li>
|
||||
<li>Orders from the last 6 months</li>
|
||||
<li>Purchase orders from the last 6 months</li>
|
||||
<li>Categories and product relationships</li>
|
||||
</ul>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user