diff --git a/frontend/src/pages/StudioPage.vue b/frontend/src/pages/StudioPage.vue
index e96769b..0045657 100644
--- a/frontend/src/pages/StudioPage.vue
+++ b/frontend/src/pages/StudioPage.vue
@@ -94,6 +94,25 @@
{{ analysisStore.running ? t('studio.analyzing') : t('studio.run') }}
+
@@ -465,6 +484,7 @@ import BboxOverlay from '../features/analysis/ui/BboxOverlay.vue'
import { ChunkPanel } from '../features/chunking'
import { useFeatureFlag } from '../features/feature-flags'
import { getPreviewUrl } from '../features/document/api'
+import { useIngestionStore } from '../features/ingestion/store'
import { useI18n } from '../shared/i18n'
import type { ChunkBbox, PipelineOptions } from '../shared/types'
@@ -472,6 +492,7 @@ const route = useRoute()
const router = useRouter()
const documentStore = useDocumentStore()
const analysisStore = useAnalysisStore()
+const ingestionStore = useIngestionStore()
const { t } = useI18n()
const chunkingEnabled = useFeatureFlag('chunking')
@@ -595,9 +616,21 @@ watch(
},
)
+async function handleIngest(): Promise {
+ const analysis = analysisStore.currentAnalysis
+ if (!analysis || !selectedDoc.value) return
+ try {
+ const count = await ingestionStore.ingest(analysis.id, selectedDoc.value.id)
+ console.warn(`Ingestion complete — ${count} chunks indexed.`)
+ } catch (e) {
+ console.error('Ingestion failed', e)
+ }
+}
+
onMounted(async () => {
await documentStore.load()
analysisStore.load()
+ ingestionStore.checkAvailability()
// Restore analysis from history via query param
const analysisId = route.query.analysisId
@@ -811,6 +844,21 @@ onBeforeUnmount(() => {
cursor: not-allowed;
}
+.topbar-btn.ingest {
+ background: var(--success, #22c55e);
+ border-color: var(--success, #22c55e);
+ color: white;
+}
+
+.topbar-btn.ingest:hover:not(:disabled) {
+ background: color-mix(in srgb, var(--success, #22c55e) 85%, black);
+}
+
+.topbar-btn.ingest:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
.topbar-btn .btn-icon {
width: 16px;
height: 16px;