diff --git a/frontend/src/features/ingestion/index.ts b/frontend/src/features/ingestion/index.ts
index 95916a3..fdedec3 100644
--- a/frontend/src/features/ingestion/index.ts
+++ b/frontend/src/features/ingestion/index.ts
@@ -1 +1,2 @@
export { useIngestionStore } from './store'
+export { default as IngestPanel } from './ui/IngestPanel.vue'
diff --git a/frontend/src/features/ingestion/ui/IngestPanel.vue b/frontend/src/features/ingestion/ui/IngestPanel.vue
new file mode 100644
index 0000000..d2f55ae
--- /dev/null
+++ b/frontend/src/features/ingestion/ui/IngestPanel.vue
@@ -0,0 +1,346 @@
+
+
+
+
+
+
{{ t('ingestion.unavailable') }}
+
+
+
+
+
+
+
+ {{ t('ingestion.document') }}
+ {{ documentName }}
+
+
+ {{ t('ingestion.chunkCount') }}
+ {{ chunkCount }}
+
+
+
+
+
+
+
+ {{ t('ingestion.stepEmbedding') }}
+
+
+
+
+ {{ t('ingestion.stepIndexing') }}
+
+
+
+
+ {{ t('ingestion.stepDone') }}
+
+
+
+
+
+ {{ ingestionStore.error }}
+
+
+
+
+
+
{{ t('ingestion.successMessage') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/pages/StudioPage.vue b/frontend/src/pages/StudioPage.vue
index 16d4c8e..3d6f24d 100644
--- a/frontend/src/pages/StudioPage.vue
+++ b/frontend/src/pages/StudioPage.vue
@@ -66,6 +66,24 @@
{{ t('studio.prepare') }}
+
@@ -94,64 +112,6 @@
{{ analysisStore.running ? t('studio.analyzing') : t('studio.run') }}
-
-
-
-
-
-
-
-
- {{ t('ingestion.stepEmbedding') }}
-
-
-
-
- {{ t('ingestion.stepIndexing') }}
-
-
-
-
- {{ t('ingestion.stepDone') }}
@@ -507,6 +467,15 @@
@rechunked="onRechunked"
/>
+
+
+
+
+
@@ -522,6 +491,7 @@ import { DocumentUpload, DocumentList } from '../features/document/index'
import { ResultTabs } from '../features/analysis/index'
import BboxOverlay from '../features/analysis/ui/BboxOverlay.vue'
import { ChunkPanel } from '../features/chunking'
+import { IngestPanel } from '../features/ingestion'
import { useFeatureFlag } from '../features/feature-flags'
import { getPreviewUrl } from '../features/document/api'
import { useI18n } from '../shared/i18n'
@@ -632,11 +602,6 @@ async function runAnalysis() {
await analysisStore.run(documentStore.selectedId, { ...pipelineOptions })
}
-async function runIngestion() {
- if (!analysisStore.currentAnalysis?.id) return
- await ingestionStore.ingest(analysisStore.currentAnalysis.id)
-}
-
function addMore() {
documentStore.selectedId = null
}
@@ -658,22 +623,12 @@ watch(currentPage, () => {
})
// Auto-switch to verify when analysis completes + refresh document data (pageCount)
-// Auto-trigger ingestion if pipeline is available (#81)
watch(
() => analysisStore.currentAnalysis?.status,
- async (status) => {
+ (status) => {
if (status === 'COMPLETED') {
mode.value = 'verify'
documentStore.load()
-
- // Auto-ingest if chunks are available and pipeline is configured
- if (
- ingestionStore.available &&
- analysisStore.currentAnalysis?.chunksJson &&
- analysisStore.currentAnalysis?.id
- ) {
- await ingestionStore.ingest(analysisStore.currentAnalysis.id)
- }
}
},
)
@@ -895,21 +850,6 @@ onBeforeUnmount(() => {
cursor: not-allowed;
}
-.topbar-btn.ingest {
- background: var(--success);
- border-color: var(--success);
- color: white;
-}
-
-.topbar-btn.ingest:hover:not(:disabled) {
- filter: brightness(1.1);
-}
-
-.topbar-btn.ingest:disabled {
- opacity: 0.6;
- cursor: not-allowed;
-}
-
.topbar-btn .btn-icon {
width: 16px;
height: 16px;
@@ -924,79 +864,6 @@ onBeforeUnmount(() => {
animation: spin 0.6s linear infinite;
}
-/* Ingestion stepper */
-.ingestion-stepper {
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 0;
- padding: 8px 20px;
- background: var(--bg-surface);
- border-bottom: 1px solid var(--border);
-}
-
-.step {
- display: flex;
- align-items: center;
- gap: 6px;
- padding: 0 8px;
-}
-
-.step-dot {
- width: 10px;
- height: 10px;
- border-radius: 50%;
- background: var(--border);
- transition: all 0.3s ease;
-}
-
-.step.active .step-dot {
- background: var(--accent);
- box-shadow: 0 0 6px var(--accent);
- animation: pulse-dot 1s ease-in-out infinite;
-}
-
-.step.done .step-dot {
- background: var(--success, #22c55e);
-}
-
-.step-label {
- font-size: 12px;
- color: var(--text-muted);
- font-weight: 500;
-}
-
-.step.active .step-label {
- color: var(--accent);
-}
-
-.step.done .step-label {
- color: var(--success, #22c55e);
-}
-
-.step-line {
- width: 40px;
- height: 2px;
- background: var(--border);
- transition: background 0.3s ease;
-}
-
-.step-line.done {
- background: var(--success, #22c55e);
-}
-
-@keyframes pulse-dot {
- 0%,
- 100% {
- transform: scale(1);
- opacity: 1;
- }
- 50% {
- transform: scale(1.3);
- opacity: 0.7;
- }
-}
-
/* Doc info bar */
.doc-infobar {
display: flex;
@@ -1541,9 +1408,10 @@ onBeforeUnmount(() => {
padding-top: 16px;
}
-/* Verify panel */
+/* Verify / Prepare / Ingest panels */
.verify-panel,
-.prepare-panel {
+.prepare-panel,
+.ingest-panel-wrapper {
height: 100%;
overflow: hidden;
display: flex;
diff --git a/frontend/src/shared/i18n.ts b/frontend/src/shared/i18n.ts
index f0c5c46..2c7ff81 100644
--- a/frontend/src/shared/i18n.ts
+++ b/frontend/src/shared/i18n.ts
@@ -109,6 +109,7 @@ const messages: Messages = {
// Chunking
'studio.prepare': 'Préparer',
+ 'studio.ingest': 'Ingérer',
'chunking.settings': 'Chunking',
'chunking.chunkerType': 'Type de chunker',
'chunking.maxTokens': 'Tokens max',
@@ -137,6 +138,9 @@ const messages: Messages = {
// Ingestion / My Documents
'ingestion.ingest': 'Ingérer',
+ 'ingestion.document': 'Document',
+ 'ingestion.chunkCount': 'Chunks prêts',
+ 'ingestion.successMessage': 'Indexation terminée avec succès !',
'ingestion.ingesting': 'Ingestion...',
'ingestion.reindex': 'Ré-indexer',
'ingestion.indexed': 'Indexé',
@@ -274,6 +278,7 @@ const messages: Messages = {
'history.open': 'Open',
'studio.prepare': 'Prepare',
+ 'studio.ingest': 'Ingest',
'chunking.settings': 'Chunking',
'chunking.chunkerType': 'Chunker type',
'chunking.maxTokens': 'Max tokens',
@@ -300,6 +305,9 @@ const messages: Messages = {
'search.hint': 'Enter a term to search through indexed chunks.',
'ingestion.ingest': 'Ingest',
+ 'ingestion.document': 'Document',
+ 'ingestion.chunkCount': 'Chunks ready',
+ 'ingestion.successMessage': 'Indexing completed successfully!',
'ingestion.ingesting': 'Ingesting...',
'ingestion.reindex': 'Re-index',
'ingestion.indexed': 'Indexed',