feat: add individual and bulk chart upgrade, fix health check URL
All checks were successful
Build & Release / build (push) Successful in 12s

This commit is contained in:
Ryan Moon
2026-04-03 21:26:35 -05:00
parent 766ad63278
commit 31684f4a15
4 changed files with 84 additions and 3 deletions

View File

@@ -228,6 +228,7 @@
<div class="table-toolbar">
<input class="search-input" id="customers-search" type="text" placeholder="Search customers…" oninput="onSearchInput()" />
<button class="btn btn-slate" onclick="loadCustomers()">Refresh</button>
<button class="btn btn-slate" id="upgrade-all-btn" onclick="upgradeAll()">Upgrade All</button>
</div>
<div class="table-wrap">
<table>
@@ -347,6 +348,7 @@
<div class="kebab-item" onclick="kebabAction('view')">View Details</div>
<div class="kebab-item" id="kebab-deactivate" onclick="kebabAction('deactivate')">Deactivate</div>
<div class="kebab-item" id="kebab-reactivate" onclick="kebabAction('reactivate')" style="display:none">Reactivate</div>
<div class="kebab-item" onclick="kebabAction('upgrade')">Upgrade Chart</div>
<div class="kebab-item danger" onclick="kebabAction('delete')">Delete</div>
<div class="kebab-item" onclick="kebabAction('record')">Remove Record Only</div>
</div>
@@ -580,6 +582,7 @@
if (action === 'view') openDetail(slug);
else if (action === 'deactivate') deactivate(slug);
else if (action === 'reactivate') reactivate(slug);
else if (action === 'upgrade') upgradeCustomer(slug);
else if (action === 'delete') openDeleteDialog(slug);
else if (action === 'record') removeRecord(slug);
}
@@ -830,6 +833,43 @@
}
}
// ── Upgrade ───────────────────────────────────────────────────────────────
async function upgradeCustomer(slug) {
const btn = event?.target;
if (btn) { btn.disabled = true; btn.textContent = 'Upgrading…'; }
try {
const res = await apiFetch(`/api/customers/${slug}/upgrade`, { method: 'POST' });
const data = await res.json();
if (!res.ok) throw new Error(data.message ?? 'Failed');
alert(`${slug} upgraded to chart ${data.version}`);
loadCustomers();
} catch (err) {
alert(`Upgrade failed: ${err.message}`);
} finally {
if (btn) { btn.disabled = false; btn.textContent = 'Upgrade Chart'; }
}
}
async function upgradeAll() {
const btn = document.getElementById('upgrade-all-btn');
btn.disabled = true;
btn.textContent = 'Upgrading…';
try {
const res = await apiFetch('/api/customers/upgrade-all', { method: 'POST' });
const data = await res.json();
if (!res.ok) throw new Error(data.message ?? 'Failed');
if (!data.upgraded.length) { alert('No provisioned customers to upgrade.'); return; }
alert(`Upgraded ${data.upgraded.length} customer(s) to chart ${data.version}:\n${data.upgraded.join(', ')}`);
loadCustomers();
} catch (err) {
alert(`Upgrade all failed: ${err.message}`);
} finally {
btn.disabled = false;
btn.textContent = 'Upgrade All';
}
}
// ── Provision ─────────────────────────────────────────────────────────────
function toggleModule(checkbox) {