diff --git a/frontend/src/components/setup/IngestDashboard.tsx b/frontend/src/components/setup/IngestDashboard.tsx new file mode 100644 index 00000000..292bd603 --- /dev/null +++ b/frontend/src/components/setup/IngestDashboard.tsx @@ -0,0 +1,179 @@ +import { useState, useEffect, useCallback } from 'react'; +import { Loader2, CheckCircle2, AlertCircle } from 'lucide-react'; +import { getSyncStatus } from '../../lib/connectors-api'; +import { SOURCE_CATALOG } from '../../types/connectors'; +import type { SyncStatus } from '../../types/connectors'; + +// --------------------------------------------------------------------------- +// ProgressRow +// --------------------------------------------------------------------------- + +function ProgressRow({ + displayName, + status, +}: { + displayName: string; + status: SyncStatus | null; +}) { + const isDone = status?.state === 'idle' && (status?.items_synced ?? 0) > 0; + const pct = + status && status.items_total > 0 + ? Math.min(100, Math.round((status.items_synced / status.items_total) * 100)) + : isDone + ? 100 + : 0; + + return ( +
+ {status.error} +
+ )} ++ {allDone + ? `Indexed ${totalSynced} items across ${connectedIds.length} source${connectedIds.length !== 1 ? 's' : ''}.` + : 'This may take a few minutes depending on your data volume.'} +
++ Sync will continue in the background +
+ )} ++ {connectedCards.length > 0 + ? `Connected ${connectedCards.length} source${connectedCards.length !== 1 ? 's' : ''}: ${connectedCards.map((c) => c!.display_name).join(', ')}.` + : 'Your personal AI is ready to help.'} + {' '}Ask anything about your work and life. +
++ Try asking +
+ {starters.map((q) => ( ++ Enter the path to your local {displayName} folder. +
++ Authorize OpenJarvis to access your {displayName} account. +
+ + > + ) : ( + <> ++ After authorizing, paste the token or code below. +
++ {displayName} reads data directly from your Mac. Make sure the app is installed and + Full Disk Access is granted to OpenJarvis in System Settings. +
++ Sources +
+ {entries.map((entry, idx) => { + const card = SOURCE_CATALOG.find((c) => c.connector_id === entry.id); + return ( ++ {activeCard.description} +
+ {activeEntry.state === 'error' && activeEntry.error && ( ++ All sources configured +
++ Choose which data sources to include in your personal knowledge base. +
+