diff --git a/src/api/connectionApi.ts b/src/api/connectionApi.ts index 72b5097..828d2f1 100644 --- a/src/api/connectionApi.ts +++ b/src/api/connectionApi.ts @@ -348,6 +348,9 @@ export interface RagDataSourceDto { ragIndexEnabled: boolean; neutralize: boolean; lastIndexed: number | null; + /** Distinct files indexed for this DataSource (one row per source document). */ + fileCount: number; + /** Embedding-sized text fragments (one per ContentChunk row, ~400 tokens each). */ chunkCount: number; } @@ -358,6 +361,7 @@ export interface RagConnectionDto { knowledgeIngestionEnabled: boolean; preferences: KnowledgePreferences; dataSources: RagDataSourceDto[]; + totalFiles: number; totalChunks: number; runningJobs: { jobId: string; progress: number; progressMessage: string }[]; lastError?: { jobId: string; errorMessage: string; finishedAt: number | null } | null; @@ -369,12 +373,17 @@ export interface RagConnectionDto { skippedPolicy: number; failed: number; durationMs: number; + /** Name of the first budget that bit (e.g. "maxBytes", "maxItems", "maxTasks"); null if walk completed naturally. */ + stoppedAtLimit?: string | null; + /** Effective limits used by the walker, for showing the value next to the limit name. */ + limits?: Record; + bytesProcessed?: number; } | null; } export interface RagInventoryDto { connections: RagConnectionDto[]; - totals: { chunks: number; bytes?: number }; + totals: { files: number; chunks: number; bytes?: number }; } export interface RagActiveJobDto { diff --git a/src/pages/RagInventoryPage.module.css b/src/pages/RagInventoryPage.module.css index a04d275..8a72cd0 100644 --- a/src/pages/RagInventoryPage.module.css +++ b/src/pages/RagInventoryPage.module.css @@ -220,6 +220,22 @@ opacity: 0.85; } +/* Sync finished, but a hard limit (maxBytes/maxItems/...) cut the walk short. + Amber, not red — the data we DID index is valid; the user just needs to + know more would have been indexed without the limit. */ +.partialBanner { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + background: #fffbeb; + border: 1px solid #fcd34d; + border-radius: 6px; + margin-bottom: 8px; + font-size: 0.8125rem; + color: #92400e; +} + .reindexBtn { display: flex; align-items: center; diff --git a/src/pages/RagInventoryPage.tsx b/src/pages/RagInventoryPage.tsx index 92dad83..7731773 100644 --- a/src/pages/RagInventoryPage.tsx +++ b/src/pages/RagInventoryPage.tsx @@ -139,6 +139,21 @@ export const RagInventoryPage: React.FC = () => { return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`; }, []); + /** Render the budget value next to its name. Bytes get MB units so the user + * immediately recognises the 200 MB default; everything else stays raw. */ + const _formatLimit = useCallback((name: string, budget: number | undefined, bytesProcessed: number | undefined): string => { + if (budget == null) return name; + if (name === 'maxBytes') { + const mb = Math.round(budget / 1024 / 1024); + const procMb = bytesProcessed != null ? ` (${(bytesProcessed / 1024 / 1024).toFixed(0)} MB ${t('verarbeitet')})` : ''; + return `${name}=${mb} MB${procMb}`; + } + if (name === 'maxFileSize') { + return `${name}=${Math.round(budget / 1024 / 1024)} MB`; + } + return `${name}=${budget}`; + }, [t]); + const scopeOptions = useMemo(() => { const opts: { value: string; label: string }[] = [ { value: 'personal', label: t('Meine Verbindungen') }, @@ -193,7 +208,9 @@ export const RagInventoryPage: React.FC = () => { {inventory && (
- {t('Total Chunks')}: + {t('Total Dateien')}: + {inventory.totals?.files ?? 0} + {t('Total Chunks')}: {inventory.totals?.chunks ?? 0} {inventory.totals?.bytes != null && inventory.totals.bytes > 0 && ( {(inventory.totals.bytes / 1024 / 1024).toFixed(1)} MB @@ -205,8 +222,13 @@ export const RagInventoryPage: React.FC = () => {
{conn.authority} {conn.externalEmail} - {conn.totalChunks > 0 && ( - {conn.totalChunks} chunks + {(conn.totalFiles > 0 || conn.totalChunks > 0) && ( + + {t('{f} Dateien · {c} Chunks', { f: conn.totalFiles, c: conn.totalChunks })} + )} +
+ ); + } + return (
@@ -293,7 +337,12 @@ export const RagInventoryPage: React.FC = () => {
{ds.label || ds.path} {ds.sourceType} - {ds.chunkCount} chunks + + {ds.fileCount} {t('Dateien')} · {ds.chunkCount} {t('Chunks')} + {ds.ragIndexEnabled ? '\uD83E\uDDE0' : '\u2014'}
))}