Spaces:
Running
Running
Seth
commited on
Commit
·
80a736e
1
Parent(s):
2a0e4eb
update
Browse files- backend/app/main.py +3 -2
- frontend/src/pages/Repository.jsx +53 -3
backend/app/main.py
CHANGED
|
@@ -188,7 +188,7 @@ async def get_asset_status(asset_id: int, db: Session = Depends(get_db)):
|
|
| 188 |
try:
|
| 189 |
cursor = conn.cursor()
|
| 190 |
cursor.execute("""
|
| 191 |
-
SELECT id, name, analysis_status, analyzed_at
|
| 192 |
FROM assets
|
| 193 |
WHERE id = %s
|
| 194 |
""", (asset_id,))
|
|
@@ -200,7 +200,8 @@ async def get_asset_status(asset_id: int, db: Session = Depends(get_db)):
|
|
| 200 |
"asset_id": row[0],
|
| 201 |
"name": row[1],
|
| 202 |
"status": row[2] or "pending",
|
| 203 |
-
"analyzed_at": row[3].isoformat() if row[3] else None
|
|
|
|
| 204 |
}
|
| 205 |
except Exception as e:
|
| 206 |
if conn:
|
|
|
|
| 188 |
try:
|
| 189 |
cursor = conn.cursor()
|
| 190 |
cursor.execute("""
|
| 191 |
+
SELECT id, name, analysis_status, analyzed_at, extracted_content
|
| 192 |
FROM assets
|
| 193 |
WHERE id = %s
|
| 194 |
""", (asset_id,))
|
|
|
|
| 200 |
"asset_id": row[0],
|
| 201 |
"name": row[1],
|
| 202 |
"status": row[2] or "pending",
|
| 203 |
+
"analyzed_at": row[3].isoformat() if row[3] else None,
|
| 204 |
+
"extracted_content": row[4] if len(row) > 4 else None # Include extracted JSON
|
| 205 |
}
|
| 206 |
except Exception as e:
|
| 207 |
if conn:
|
frontend/src/pages/Repository.jsx
CHANGED
|
@@ -19,7 +19,8 @@ import {
|
|
| 19 |
Plus,
|
| 20 |
X,
|
| 21 |
Check,
|
| 22 |
-
File
|
|
|
|
| 23 |
} from 'lucide-react';
|
| 24 |
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
| 25 |
import { Button } from '@/components/ui/button';
|
|
@@ -231,10 +232,14 @@ export default function Repository() {
|
|
| 231 |
const data = await response.json();
|
| 232 |
setPdfPages(data);
|
| 233 |
} else {
|
| 234 |
-
|
|
|
|
|
|
|
|
|
|
| 235 |
}
|
| 236 |
} catch (error) {
|
| 237 |
console.error('Error loading PDF pages:', error);
|
|
|
|
| 238 |
} finally {
|
| 239 |
setIsLoadingPdf(false);
|
| 240 |
}
|
|
@@ -284,7 +289,8 @@ export default function Repository() {
|
|
| 284 |
...prev,
|
| 285 |
[fileName]: {
|
| 286 |
status: status.status,
|
| 287 |
-
message: getStatusMessage(status.status)
|
|
|
|
| 288 |
}
|
| 289 |
}));
|
| 290 |
|
|
@@ -541,6 +547,33 @@ export default function Repository() {
|
|
| 541 |
style={{ width: `${getProgressValue()}%` }}
|
| 542 |
/>
|
| 543 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 544 |
</div>
|
| 545 |
)}
|
| 546 |
</div>
|
|
@@ -998,6 +1031,23 @@ export default function Repository() {
|
|
| 998 |
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mb-4"></div>
|
| 999 |
<p className="text-slate-600">Converting PDF pages to images...</p>
|
| 1000 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1001 |
) : pdfPages && pdfPages.pages ? (
|
| 1002 |
<div className="space-y-6">
|
| 1003 |
<div className="text-sm text-slate-600 bg-blue-50 p-3 rounded-lg">
|
|
|
|
| 19 |
Plus,
|
| 20 |
X,
|
| 21 |
Check,
|
| 22 |
+
File,
|
| 23 |
+
Copy
|
| 24 |
} from 'lucide-react';
|
| 25 |
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
| 26 |
import { Button } from '@/components/ui/button';
|
|
|
|
| 232 |
const data = await response.json();
|
| 233 |
setPdfPages(data);
|
| 234 |
} else {
|
| 235 |
+
const errorData = await response.json().catch(() => ({ detail: 'Failed to load PDF' }));
|
| 236 |
+
console.error('Failed to load PDF pages:', errorData);
|
| 237 |
+
// Store error message for display
|
| 238 |
+
setPdfPages({ error: errorData.detail || 'Failed to load PDF preview' });
|
| 239 |
}
|
| 240 |
} catch (error) {
|
| 241 |
console.error('Error loading PDF pages:', error);
|
| 242 |
+
setPdfPages({ error: error.message || 'Failed to load PDF preview' });
|
| 243 |
} finally {
|
| 244 |
setIsLoadingPdf(false);
|
| 245 |
}
|
|
|
|
| 289 |
...prev,
|
| 290 |
[fileName]: {
|
| 291 |
status: status.status,
|
| 292 |
+
message: getStatusMessage(status.status),
|
| 293 |
+
extractedContent: status.extracted_content || null // Store extracted JSON
|
| 294 |
}
|
| 295 |
}));
|
| 296 |
|
|
|
|
| 547 |
style={{ width: `${getProgressValue()}%` }}
|
| 548 |
/>
|
| 549 |
</div>
|
| 550 |
+
{/* JSON Output Display */}
|
| 551 |
+
{progress?.status === 'completed' && progress?.extractedContent && (
|
| 552 |
+
<div className="mt-3 p-3 bg-slate-50 rounded-lg border border-slate-200">
|
| 553 |
+
<div className="flex items-center justify-between mb-2">
|
| 554 |
+
<p className="text-xs font-medium text-slate-700">Extracted JSON Output:</p>
|
| 555 |
+
<Button
|
| 556 |
+
variant="ghost"
|
| 557 |
+
size="sm"
|
| 558 |
+
className="h-6 px-2 text-xs"
|
| 559 |
+
onClick={() => {
|
| 560 |
+
const jsonStr = JSON.stringify(progress.extractedContent, null, 2);
|
| 561 |
+
navigator.clipboard.writeText(jsonStr).then(() => {
|
| 562 |
+
alert('JSON copied to clipboard!');
|
| 563 |
+
}).catch(() => {
|
| 564 |
+
alert('Failed to copy JSON');
|
| 565 |
+
});
|
| 566 |
+
}}
|
| 567 |
+
>
|
| 568 |
+
<Copy className="w-3 h-3 mr-1" />
|
| 569 |
+
Copy
|
| 570 |
+
</Button>
|
| 571 |
+
</div>
|
| 572 |
+
<pre className="text-xs text-slate-600 bg-white p-2 rounded border border-slate-200 max-h-40 overflow-auto font-mono">
|
| 573 |
+
{JSON.stringify(progress.extractedContent, null, 2)}
|
| 574 |
+
</pre>
|
| 575 |
+
</div>
|
| 576 |
+
)}
|
| 577 |
</div>
|
| 578 |
)}
|
| 579 |
</div>
|
|
|
|
| 1031 |
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mb-4"></div>
|
| 1032 |
<p className="text-slate-600">Converting PDF pages to images...</p>
|
| 1033 |
</div>
|
| 1034 |
+
) : pdfPages && pdfPages.error ? (
|
| 1035 |
+
<div className="flex flex-col items-center justify-center p-12 bg-red-50 rounded-lg border border-red-200">
|
| 1036 |
+
<FileText className="w-16 h-16 text-red-400 mb-4" />
|
| 1037 |
+
<p className="text-red-600 font-medium mb-2">Failed to load PDF preview</p>
|
| 1038 |
+
<p className="text-red-500 text-sm mb-4 text-center max-w-md">{pdfPages.error}</p>
|
| 1039 |
+
<p className="text-slate-600 text-xs mb-4 text-center max-w-md">
|
| 1040 |
+
This might be because poppler-utils is not installed. PDFs can still be downloaded.
|
| 1041 |
+
</p>
|
| 1042 |
+
<Button
|
| 1043 |
+
onClick={() => window.open(`/api/assets/${previewAsset.id}/download`, '_blank')}
|
| 1044 |
+
variant="outline"
|
| 1045 |
+
className="border-red-200 text-red-600 hover:bg-red-100"
|
| 1046 |
+
>
|
| 1047 |
+
<Download className="w-4 h-4 mr-2" />
|
| 1048 |
+
Download PDF
|
| 1049 |
+
</Button>
|
| 1050 |
+
</div>
|
| 1051 |
) : pdfPages && pdfPages.pages ? (
|
| 1052 |
<div className="space-y-6">
|
| 1053 |
<div className="text-sm text-slate-600 bg-blue-50 p-3 rounded-lg">
|