Skip to content

Commit d9f430c

Browse files
committed
Updated status indicators
1 parent c21f5cf commit d9f430c

3 files changed

Lines changed: 173 additions & 10 deletions

File tree

frontend-next/src/app/explore/page.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,14 @@ function parseDocuments(documents: Document[]): ProcessedDocument[] {
121121
errorsStr = JSON.stringify(doc.errors)
122122
}
123123

124-
// Check for actual errors - state.error boolean OR non-empty errors
124+
// Check for actual errors - state.error boolean OR non-empty errors array
125125
const hasError = state.error === true || (errorsStr.length > 0 && errorsStr !== '[]')
126126
const errorMessage = hasError ? errorsStr : ""
127127

128-
// Determine status - only failed if there's an actual error
128+
// Determine status - failed takes priority if there are any errors
129129
let status: "completed" | "processing" | "failed" = "processing"
130-
if (finished) status = "completed"
131-
else if (hasError) status = "failed"
130+
if (hasError) status = "failed"
131+
else if (finished) status = "completed"
132132

133133
return {
134134
id: doc.id,
@@ -652,6 +652,24 @@ export default function ExplorePage() {
652652
setDocumentsToDelete([doc])
653653
setDeleteDialogOpen(true)
654654
}}
655+
onRefresh={async () => {
656+
// Refresh the selected document from the API to get latest state
657+
if (selectedDocument) {
658+
try {
659+
const doc = await backendClient.getDocument(selectedDocument.id)
660+
const [refreshedDoc] = parseDocuments([doc])
661+
if (refreshedDoc) {
662+
setSelectedDocument(refreshedDoc)
663+
// Also update in the documents list
664+
setDocuments(prev => prev.map(d =>
665+
d.id === refreshedDoc.id ? refreshedDoc : d
666+
))
667+
}
668+
} catch (error) {
669+
console.error("Failed to refresh document:", error)
670+
}
671+
}
672+
}}
655673
/>
656674

657675
{/* Delete Confirmation Dialog */}

frontend-next/src/app/settings/page.tsx

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import {
1313
CheckCircle,
1414
AlertCircle,
1515
Info,
16+
Terminal,
17+
Cloud,
18+
FileCode,
1619
} from "lucide-react"
1720
import { toast } from "sonner"
1821

@@ -35,6 +38,12 @@ import {
3538
AlertDescription,
3639
AlertTitle,
3740
} from "@/components/ui/alert"
41+
import {
42+
Accordion,
43+
AccordionContent,
44+
AccordionItem,
45+
AccordionTrigger,
46+
} from "@/components/ui/accordion"
3847
import { backendClient } from "@/lib/api-client"
3948

4049
interface OpenAISettingsResponse {
@@ -560,6 +569,120 @@ export default function SettingsPage() {
560569
)}
561570
</CardContent>
562571
</Card>
572+
573+
{/* Persistent Changes Instructions */}
574+
<Card className="md:col-span-2">
575+
<CardHeader>
576+
<div className="flex items-center gap-2">
577+
<Info className="h-5 w-5 text-muted-foreground" />
578+
<CardTitle>Making Changes Permanent</CardTitle>
579+
</div>
580+
<CardDescription>
581+
Runtime changes above are temporary. For persistent changes that survive container restarts, update your deployment configuration.
582+
</CardDescription>
583+
</CardHeader>
584+
<CardContent>
585+
<Alert className="mb-6">
586+
<AlertCircle className="h-4 w-4" />
587+
<AlertTitle>Important</AlertTitle>
588+
<AlertDescription>
589+
Settings configured above are stored in memory and will be reset when the container restarts.
590+
For production deployments, update the environment variables using one of the methods below.
591+
</AlertDescription>
592+
</Alert>
593+
594+
<Accordion type="single" collapsible className="w-full">
595+
<AccordionItem value="azure-portal">
596+
<AccordionTrigger>
597+
<div className="flex items-center gap-2">
598+
<Cloud className="h-4 w-4" />
599+
Option 1: Update via Azure Portal (Recommended)
600+
</div>
601+
</AccordionTrigger>
602+
<AccordionContent className="space-y-3 text-sm">
603+
<ol className="list-decimal list-inside space-y-2 text-muted-foreground">
604+
<li>Go to <strong>Azure Portal</strong><strong>Container Apps</strong><strong>Your Backend App</strong></li>
605+
<li>Navigate to <strong>Settings</strong><strong>Environment variables</strong></li>
606+
<li>Update OpenAI variables:
607+
<ul className="list-disc list-inside ml-4 mt-1">
608+
<li><code className="bg-muted px-1 rounded">AZURE_OPENAI_ENDPOINT</code></li>
609+
<li><code className="bg-muted px-1 rounded">AZURE_OPENAI_API_KEY</code></li>
610+
<li><code className="bg-muted px-1 rounded">AZURE_OPENAI_DEPLOYMENT_NAME</code></li>
611+
</ul>
612+
</li>
613+
<li>For OCR provider (optional):
614+
<ul className="list-disc list-inside ml-4 mt-1">
615+
<li><code className="bg-muted px-1 rounded">OCR_PROVIDER</code> - Set to <code className="bg-muted px-1 rounded">azure</code> or <code className="bg-muted px-1 rounded">mistral</code></li>
616+
<li><code className="bg-muted px-1 rounded">MISTRAL_ENDPOINT</code> - Mistral API endpoint (if using Mistral)</li>
617+
<li><code className="bg-muted px-1 rounded">MISTRAL_API_KEY</code> - Mistral API key (if using Mistral)</li>
618+
<li><code className="bg-muted px-1 rounded">MISTRAL_DOC_AI_MODEL</code> - Model name (default: mistral-document-ai-2505)</li>
619+
</ul>
620+
</li>
621+
<li><strong>Restart</strong> the container app for changes to take effect</li>
622+
</ol>
623+
</AccordionContent>
624+
</AccordionItem>
625+
626+
<AccordionItem value="azure-cli">
627+
<AccordionTrigger>
628+
<div className="flex items-center gap-2">
629+
<Terminal className="h-4 w-4" />
630+
Option 2: Update via Azure CLI
631+
</div>
632+
</AccordionTrigger>
633+
<AccordionContent className="space-y-4">
634+
<div>
635+
<p className="text-sm text-muted-foreground mb-2">Update OpenAI settings:</p>
636+
<div className="bg-muted rounded-lg p-4 font-mono text-sm overflow-x-auto">
637+
<pre className="whitespace-pre-wrap">{`az containerapp update \\
638+
--name <your-backend-app-name> \\
639+
--resource-group <your-resource-group> \\
640+
--set-env-vars \\
641+
AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/" \\
642+
AZURE_OPENAI_API_KEY="your-api-key" \\
643+
AZURE_OPENAI_DEPLOYMENT_NAME="your-deployment-name"`}</pre>
644+
</div>
645+
</div>
646+
<div>
647+
<p className="text-sm text-muted-foreground mb-2">Update OCR provider (optional - for Mistral):</p>
648+
<div className="bg-muted rounded-lg p-4 font-mono text-sm overflow-x-auto">
649+
<pre className="whitespace-pre-wrap">{`az containerapp update \\
650+
--name <your-backend-app-name> \\
651+
--resource-group <your-resource-group> \\
652+
--set-env-vars \\
653+
OCR_PROVIDER="mistral" \\
654+
MISTRAL_ENDPOINT="https://your-endpoint.services.ai.azure.com/..." \\
655+
MISTRAL_API_KEY="your-mistral-key" \\
656+
MISTRAL_DOC_AI_MODEL="mistral-document-ai-2505"`}</pre>
657+
</div>
658+
</div>
659+
</AccordionContent>
660+
</AccordionItem>
661+
662+
<AccordionItem value="azd">
663+
<AccordionTrigger>
664+
<div className="flex items-center gap-2">
665+
<FileCode className="h-4 w-4" />
666+
Option 3: Update via Infrastructure (azd)
667+
</div>
668+
</AccordionTrigger>
669+
<AccordionContent className="space-y-3 text-sm">
670+
<p className="text-muted-foreground">If you&apos;re using Azure Developer CLI (azd):</p>
671+
<ol className="list-decimal list-inside space-y-2 text-muted-foreground">
672+
<li>Update the environment variables in your <code className="bg-muted px-1 rounded">infra/main.parameters.json</code> file</li>
673+
<li>Available environment variables:
674+
<ul className="list-disc list-inside ml-4 mt-1">
675+
<li><code className="bg-muted px-1 rounded">AZURE_OPENAI_ENDPOINT</code>, <code className="bg-muted px-1 rounded">AZURE_OPENAI_API_KEY</code>, <code className="bg-muted px-1 rounded">AZURE_OPENAI_DEPLOYMENT_NAME</code></li>
676+
<li><code className="bg-muted px-1 rounded">OCR_PROVIDER</code>, <code className="bg-muted px-1 rounded">MISTRAL_ENDPOINT</code>, <code className="bg-muted px-1 rounded">MISTRAL_API_KEY</code>, <code className="bg-muted px-1 rounded">MISTRAL_DOC_AI_MODEL</code></li>
677+
</ul>
678+
</li>
679+
<li>Run <code className="bg-muted px-1 rounded">azd up</code> to redeploy with new settings</li>
680+
</ol>
681+
</AccordionContent>
682+
</AccordionItem>
683+
</Accordion>
684+
</CardContent>
685+
</Card>
563686
</div>
564687
</PageContainer>
565688
)

frontend-next/src/components/documents/document-detail-sheet.tsx

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ interface DocumentDetailSheetProps {
6767
onClose: () => void
6868
onReprocess: (doc: ProcessedDocument) => void
6969
onDelete: (doc: ProcessedDocument) => void
70+
onRefresh?: () => void
7071
}
7172

7273
interface ChatMessage {
@@ -88,6 +89,7 @@ export function DocumentDetailSheet({
8889
onClose,
8990
onReprocess,
9091
onDelete,
92+
onRefresh,
9193
}: DocumentDetailSheetProps) {
9294
const [fullDocument, setFullDocument] = React.useState<Document | null>(null)
9395
const [isLoading, setIsLoading] = React.useState(false)
@@ -325,6 +327,25 @@ export function DocumentDetailSheet({
325327
<div className="flex items-center gap-2 text-sm text-muted-foreground">
326328
<Badge variant="secondary">{document.dataset}</Badge>
327329
<span></span>
330+
{document.status === "completed" && (
331+
<Badge variant="default" className="bg-green-500 hover:bg-green-500">
332+
<CheckCircle className="h-3 w-3 mr-1" />
333+
Completed
334+
</Badge>
335+
)}
336+
{document.status === "processing" && (
337+
<Badge variant="secondary" className="bg-yellow-500/20 text-yellow-600 hover:bg-yellow-500/20">
338+
<Clock className="h-3 w-3 mr-1" />
339+
Processing
340+
</Badge>
341+
)}
342+
{document.status === "failed" && (
343+
<Badge variant="destructive">
344+
<XCircle className="h-3 w-3 mr-1" />
345+
Failed
346+
</Badge>
347+
)}
348+
<span></span>
328349
<span>{formatDate(document.timestamp)}</span>
329350
</div>
330351
</div>
@@ -337,8 +358,9 @@ export function DocumentDetailSheet({
337358
setIsRefreshing(true)
338359
await loadFullDocument()
339360
await loadCorrections()
361+
// Notify parent to refresh document list for status updates
362+
onRefresh?.()
340363
setIsRefreshing(false)
341-
toast.success("Document refreshed")
342364
}}
343365
disabled={isRefreshing}
344366
>
@@ -361,31 +383,31 @@ export function DocumentDetailSheet({
361383
<div className="flex items-center justify-between gap-6">
362384
<ProcessingStep
363385
label="File Landed"
364-
completed={document.fileLanded}
386+
completed={processingState?.file_landed as boolean ?? document.fileLanded}
365387
hasError={hasActualErrors && !document.fileLanded}
366388
/>
367389
<div className="h-[2px] flex-1 bg-border" />
368390
<ProcessingStep
369391
label="OCR"
370-
completed={document.ocrCompleted}
392+
completed={processingState?.ocr_completed as boolean ?? document.ocrCompleted}
371393
hasError={hasActualErrors && document.fileLanded && !document.ocrCompleted}
372394
/>
373395
<div className="h-[2px] flex-1 bg-border" />
374396
<ProcessingStep
375397
label="Extraction"
376-
completed={document.gptExtraction}
398+
completed={processingState?.gpt_extraction_completed as boolean ?? document.gptExtraction}
377399
hasError={hasActualErrors && document.ocrCompleted && !document.gptExtraction}
378400
/>
379401
<div className="h-[2px] flex-1 bg-border" />
380402
<ProcessingStep
381403
label="Evaluation"
382-
completed={document.gptEvaluation}
404+
completed={processingState?.gpt_evaluation_completed as boolean ?? document.gptEvaluation}
383405
hasError={hasActualErrors && document.gptExtraction && !document.gptEvaluation}
384406
/>
385407
<div className="h-[2px] flex-1 bg-border" />
386408
<ProcessingStep
387409
label="Summary"
388-
completed={document.gptSummary}
410+
completed={processingState?.gpt_summary_completed as boolean ?? document.gptSummary}
389411
hasError={hasActualErrors && document.gptEvaluation && !document.gptSummary}
390412
/>
391413
</div>

0 commit comments

Comments
 (0)