Merge pull request #226 from builderz-labs/fix/issue-215-workspace-pending-state
fix(workspaces): unblock pending tenant bootstrap flow
This commit is contained in:
commit
008bba4afb
|
|
@ -395,6 +395,34 @@ export function SuperAdminPanel() {
|
|||
}
|
||||
}
|
||||
|
||||
const approveAndRunJob = async (jobId: number) => {
|
||||
setBusyJobId(jobId)
|
||||
try {
|
||||
const approveRes = await fetch(`/api/super/provision-jobs/${jobId}`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ action: 'approve' }),
|
||||
})
|
||||
const approveJson = await approveRes.json().catch(() => ({}))
|
||||
if (!approveRes.ok) throw new Error(approveJson?.error || `Failed to approve job #${jobId}`)
|
||||
|
||||
const runRes = await fetch(`/api/super/provision-jobs/${jobId}/run`, { method: 'POST' })
|
||||
const runJson = await runRes.json().catch(() => ({}))
|
||||
if (!runRes.ok) throw new Error(runJson?.error || `Failed to run job #${jobId}`)
|
||||
|
||||
showFeedback(true, `Job #${jobId} approved and executed`)
|
||||
await load()
|
||||
await loadJobDetail(jobId)
|
||||
} catch (e: any) {
|
||||
showFeedback(false, e?.message || `Failed to approve/run job #${jobId}`)
|
||||
await load()
|
||||
await loadJobDetail(jobId)
|
||||
} finally {
|
||||
setBusyJobId(null)
|
||||
setOpenActionMenu(null)
|
||||
}
|
||||
}
|
||||
|
||||
const openDecommissionDialog = (tenant: TenantRow) => {
|
||||
setOpenActionMenu(null)
|
||||
setDecommissionDialog({
|
||||
|
|
@ -884,11 +912,11 @@ export function SuperAdminPanel() {
|
|||
View events
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setJobState(job.id, 'approve')}
|
||||
onClick={() => Number(job.dry_run) === 1 ? approveAndRunJob(job.id) : setJobState(job.id, 'approve')}
|
||||
disabled={busyJobId === job.id || !['queued', 'rejected', 'failed'].includes(job.status)}
|
||||
className="w-full px-3 py-2 text-xs text-emerald-400 hover:bg-emerald-500/10 disabled:opacity-40"
|
||||
>
|
||||
Approve
|
||||
{Number(job.dry_run) === 1 ? 'Approve + Run' : 'Approve'}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setJobState(job.id, 'reject')}
|
||||
|
|
|
|||
|
|
@ -817,9 +817,14 @@ export async function executeProvisionJob(jobId: number, actor: string) {
|
|||
jobId,
|
||||
)
|
||||
|
||||
const completedTenantStatus = dryRun
|
||||
? previousTenantStatus
|
||||
: (jobType === 'decommission' ? 'suspended' : 'active')
|
||||
const completedTenantStatus = (() => {
|
||||
if (jobType === 'decommission') {
|
||||
return dryRun ? previousTenantStatus : 'suspended'
|
||||
}
|
||||
// For bootstrap/update jobs, mark tenant active when the workflow completes,
|
||||
// even in dry-run mode, so workspace lifecycle is not stuck in pending.
|
||||
return 'active'
|
||||
})()
|
||||
db.prepare(`
|
||||
UPDATE tenants
|
||||
SET status = ?, updated_at = (unixepoch())
|
||||
|
|
|
|||
Loading…
Reference in New Issue