fc5: migration Pinia store — trigger + FormData upload + 2s poll + history list
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import { useApi } from '../composables/useApi.js'
|
||||
|
||||
const POLL_MS = 2000
|
||||
|
||||
export const useMigrationStore = defineStore('migration', () => {
|
||||
const api = useApi()
|
||||
|
||||
const activeRun = ref(null)
|
||||
const recentRuns = ref([])
|
||||
const error = ref(null)
|
||||
const loading = ref(false)
|
||||
|
||||
let pollHandle = null
|
||||
|
||||
async function trigger(kind, params, file = null) {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
try {
|
||||
let body
|
||||
if (file) {
|
||||
// Multipart upload for ingest kinds.
|
||||
const form = new FormData()
|
||||
form.append('export_file', file)
|
||||
if (params && params.dry_run) form.append('dry_run', 'true')
|
||||
if (params && params.force) form.append('force', 'true')
|
||||
body = await api.post(`/api/migrate/${kind}`, { body: form })
|
||||
} else {
|
||||
body = await api.post(`/api/migrate/${kind}`, { body: params || {} })
|
||||
}
|
||||
await loadRun(body.run_id)
|
||||
pollActive(body.run_id)
|
||||
return body
|
||||
} catch (e) {
|
||||
error.value = e
|
||||
throw e
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function loadRun(runId) {
|
||||
activeRun.value = await api.get(`/api/migrate/runs/${runId}`)
|
||||
}
|
||||
|
||||
async function loadRecent() {
|
||||
recentRuns.value = await api.get('/api/migrate/runs', { params: { limit: 10 } })
|
||||
}
|
||||
|
||||
function pollActive(runId) {
|
||||
stopPolling()
|
||||
pollHandle = setInterval(async () => {
|
||||
try {
|
||||
const run = await api.get(`/api/migrate/runs/${runId}`)
|
||||
activeRun.value = run
|
||||
if (run.status === 'ok' || run.status === 'error') {
|
||||
stopPolling()
|
||||
await loadRecent()
|
||||
}
|
||||
} catch (e) {
|
||||
error.value = e
|
||||
stopPolling()
|
||||
}
|
||||
}, POLL_MS)
|
||||
}
|
||||
|
||||
function stopPolling() {
|
||||
if (pollHandle) {
|
||||
clearInterval(pollHandle)
|
||||
pollHandle = null
|
||||
}
|
||||
}
|
||||
|
||||
const isRunning = computed(
|
||||
() => activeRun.value && activeRun.value.status === 'running',
|
||||
)
|
||||
|
||||
return {
|
||||
activeRun, recentRuns, error, loading, isRunning,
|
||||
trigger, loadRun, loadRecent, pollActive, stopPolling,
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user