feat(operator): create tenant from the operator UI
Wires the previously-dead 'New tenant' button on /tenants to a modal that collects slug + name + plan + optional primary domain, POSTs to the existing platform-api /tenants endpoint via a new operator proxy, and navigates into the freshly-created tenant detail page. Slug auto-derives from the name until the operator types in the slug field themselves. Billing details and provisioning are still done from the tenant detail page after creation — this modal is the minimum that backend validators will accept.
This commit is contained in:
@@ -7,6 +7,16 @@ const { data: tenants, refresh, pending } = await useFetch<Tenant[]>('/api/tenan
|
||||
|
||||
const search = ref('')
|
||||
const statusFilter = ref<'all' | TenantStatus>('all')
|
||||
const createOpen = ref(false)
|
||||
|
||||
async function onCreated(tenant: Tenant) {
|
||||
createOpen.value = false
|
||||
// Refresh the list so the new row appears immediately, then jump into the
|
||||
// detail page — that's where the operator will configure domains, billing,
|
||||
// and trigger provisioning.
|
||||
await refresh()
|
||||
await navigateTo(`/tenants/${tenant.slug}`)
|
||||
}
|
||||
|
||||
const filtered = computed(() => {
|
||||
const q = search.value.trim().toLowerCase()
|
||||
@@ -50,13 +60,15 @@ function navTo(t: Tenant) {
|
||||
<template #leading><UiIcon name="refresh" :size="13" /></template>
|
||||
Refresh
|
||||
</UiButton>
|
||||
<UiButton variant="primary">
|
||||
<UiButton variant="primary" @click="createOpen = true">
|
||||
<template #leading><UiIcon name="plus" :size="13" /></template>
|
||||
New tenant
|
||||
</UiButton>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<NewTenantModal :open="createOpen" @close="createOpen = false" @created="onCreated" />
|
||||
|
||||
<div class="stage">
|
||||
<div class="filters">
|
||||
<div class="search">
|
||||
|
||||
Reference in New Issue
Block a user