diff --git a/frontend/src/features/tenants/components/EditTenantDialog.tsx b/frontend/src/features/tenants/components/EditTenantDialog.tsx index 10a260613..5b9562738 100644 --- a/frontend/src/features/tenants/components/EditTenantDialog.tsx +++ b/frontend/src/features/tenants/components/EditTenantDialog.tsx @@ -6,13 +6,10 @@ import { cn } from '@/shared/lib/utils' import { Button } from '@/shared/components/ui/button' import { Input } from '@/shared/components/ui/input' import { tenantsHttpService } from '../services/tenants-http.service' -import type { Tenant, TenantStatus } from '../types/tenant.types' +import type { Tenant } from '../types/tenant.types' import { Modal } from './Modal' import { Field } from './Field' import { tenantError } from './tenant-error' -import { ReactivateTenantDialog } from './ReactivateTenantDialog' - -const STATUSES: TenantStatus[] = ['ACTIVE', 'SUSPENDED'] export function EditTenantDialog({ tenant, @@ -22,27 +19,10 @@ export function EditTenantDialog({ tenant: Tenant onClose: () => void onSaved: () => void -}) { - if (tenant.status === 'TERMINATED') { - return - } - - return -} - -function EditTenantForm({ - tenant, - onClose, - onSaved, -}: { - tenant: Tenant - onClose: () => void - onSaved: () => void }) { const { t } = useTranslation() const [name, setName] = useState(tenant.name) const [domain, setDomain] = useState(tenant.domain) - const [status, setStatus] = useState(tenant.status) const [capped, setCapped] = useState(tenant.limits.maxAIRequests != null) const [maxAI, setMaxAI] = useState(String(tenant.limits.maxAIRequests ?? '')) const [busy, setBusy] = useState(false) @@ -58,7 +38,6 @@ function EditTenantForm({ await tenantsHttpService.update(tenant.id, { name: name.trim(), domain: domain.trim().toLowerCase(), - status, // Clearing the cap sends an explicit null: omitting the field would // mean "leave it as it is", which is the opposite of the intent. maxAIRequests: capped ? parsedMax : null, @@ -96,29 +75,6 @@ function EditTenantForm({ setDomain(e.target.value)} className="font-mono" /> - -
- {STATUSES.map((s) => ( - - ))} -
- {status === 'SUSPENDED' && ( -

- {t('tenants.fields.suspendedWarning')} -

- )} -
- - {!terminated ? ( + {tenant.status === 'ACTIVE' ? ( ) : ( )} + diff --git a/frontend/src/features/tenants/pages/TenantsPage.tsx b/frontend/src/features/tenants/pages/TenantsPage.tsx index c3541529b..9db906a9f 100644 --- a/frontend/src/features/tenants/pages/TenantsPage.tsx +++ b/frontend/src/features/tenants/pages/TenantsPage.tsx @@ -20,6 +20,7 @@ import { TenantCard } from '../components/TenantCard' import { CreateTenantDialog } from '../components/CreateTenantDialog' import { EditTenantDialog } from '../components/EditTenantDialog' import { TerminateDialog } from '../components/TerminateDialog' +import { ReactivateTenantDialog } from '../components/ReactivateTenantDialog' import { PermanentDeleteDialog } from '../components/PermanentDeleteDialog' /* ───────────────────────────────────────────────────────────────────────── @@ -34,7 +35,8 @@ export function TenantsPage() { const [query, setQuery] = useState('') const [creating, setCreating] = useState(false) const [editing, setEditing] = useState(null) - const [terminating, setTerminating] = useState(null) + const [deactivating, setDeactivating] = useState(null) + const [activating, setActivating] = useState(null) const [deletingPermanently, setDeletingPermanently] = useState(null) const load = useCallback(async () => { @@ -128,7 +130,8 @@ export function TenantsPage() { tenant={tenant} readable={canReadTenant(tenant)} onEdit={() => setEditing(tenant)} - onTerminate={() => setTerminating(tenant)} + onActivate={() => setActivating(tenant)} + onDeactivate={() => setDeactivating(tenant)} onDelete={() => setDeletingPermanently(tenant)} /> ))} @@ -157,12 +160,22 @@ export function TenantsPage() { }} /> )} - {terminating && ( + {deactivating && ( setTerminating(null)} + tenant={deactivating} + onClose={() => setDeactivating(null)} onDone={() => { - setTerminating(null) + setDeactivating(null) + void load() + }} + /> + )} + {activating && ( + setActivating(null)} + onSaved={() => { + setActivating(null) void load() }} /> diff --git a/frontend/src/shared/i18n/locales/de.json b/frontend/src/shared/i18n/locales/de.json index 6d37ca983..927736c75 100644 --- a/frontend/src/shared/i18n/locales/de.json +++ b/frontend/src/shared/i18n/locales/de.json @@ -5428,7 +5428,8 @@ }, "card": { "edit": "Bearbeiten", - "terminate": "Beenden", + "activate": "Aktivieren", + "deactivate": "Deaktivieren", "deletePermanent": "Endgültig löschen", "noAccess": "Dieser Mandant hat Ihnen keinen Zugriff gewährt.", "loadingStats": "Wird gelesen…", @@ -5464,15 +5465,15 @@ "submit": "Änderungen speichern" }, "terminate": { - "title": "Diesen Mandanten beenden?", - "body": "Niemand aus {{name}} kann sich mehr anmelden. Die Daten bleiben erhalten, ein Betreiber kann es also zurücknehmen — aber der Kunde ist ab sofort offline.", + "title": "Diesen Mandanten deaktivieren?", + "body": "Niemand aus {{name}} kann sich mehr anmelden. Die Daten bleiben erhalten, es ist also umkehrbar — aber der Kunde ist ab sofort offline.", "confirmLabel": "Zum Bestätigen {{name}} eingeben", - "submit": "Beenden" + "submit": "Deaktivieren" }, "reactivate": { - "title": "Diesen Mandanten reaktivieren?", + "title": "Diesen Mandanten aktivieren?", "body": "{{name}} kann sich wieder anmelden. Die aufbewahrten Daten werden unverändert wiederhergestellt.", - "submit": "Reaktivieren" + "submit": "Aktivieren" }, "deletePermanent": { "title": "Diesen Mandanten für immer löschen?", diff --git a/frontend/src/shared/i18n/locales/en.json b/frontend/src/shared/i18n/locales/en.json index b23ed55c4..ad0950b77 100644 --- a/frontend/src/shared/i18n/locales/en.json +++ b/frontend/src/shared/i18n/locales/en.json @@ -5408,7 +5408,8 @@ }, "card": { "edit": "Edit", - "terminate": "Terminate", + "activate": "Activate", + "deactivate": "Deactivate", "deletePermanent": "Delete permanently", "noAccess": "This tenant has not granted you access.", "loadingStats": "Reading…", @@ -5444,15 +5445,15 @@ "submit": "Save changes" }, "terminate": { - "title": "Terminate this tenant?", - "body": "Nobody in {{name}} will be able to sign in. Their data is kept, so this is reversible by an operator, but it takes the customer offline now.", + "title": "Deactivate this tenant?", + "body": "Nobody in {{name}} will be able to sign in. Their data is kept, so this is reversible, but it takes the customer offline now.", "confirmLabel": "Type {{name}} to confirm", - "submit": "Terminate" + "submit": "Deactivate" }, "reactivate": { - "title": "Reactivate this tenant?", + "title": "Activate this tenant?", "body": "{{name}} will be able to sign in again. Their preserved data is restored as-is.", - "submit": "Reactivate" + "submit": "Activate" }, "deletePermanent": { "title": "Delete this tenant forever?", diff --git a/frontend/src/shared/i18n/locales/es.json b/frontend/src/shared/i18n/locales/es.json index 5632d2e52..7427876e2 100644 --- a/frontend/src/shared/i18n/locales/es.json +++ b/frontend/src/shared/i18n/locales/es.json @@ -5390,7 +5390,8 @@ }, "card": { "edit": "Editar", - "terminate": "Terminar", + "activate": "Activar", + "deactivate": "Desactivar", "deletePermanent": "Eliminar permanentemente", "noAccess": "Este tenant no te ha dado acceso.", "loadingStats": "Leyendo…", @@ -5426,15 +5427,15 @@ "submit": "Guardar cambios" }, "terminate": { - "title": "¿Terminar este tenant?", - "body": "Nadie de {{name}} podrá iniciar sesión. Sus datos se conservan, así que un operador puede revertirlo, pero deja al cliente fuera ahora mismo.", + "title": "¿Desactivar este tenant?", + "body": "Nadie de {{name}} podrá iniciar sesión. Sus datos se conservan, así que es reversible, pero deja al cliente fuera ahora mismo.", "confirmLabel": "Escribe {{name}} para confirmar", - "submit": "Terminar" + "submit": "Desactivar" }, "reactivate": { - "title": "¿Reactivar este tenant?", + "title": "¿Activar este tenant?", "body": "{{name}} podrá iniciar sesión de nuevo. Sus datos conservados se restauran tal cual.", - "submit": "Reactivar" + "submit": "Activar" }, "deletePermanent": { "title": "¿Eliminar este tenant para siempre?", diff --git a/frontend/src/shared/i18n/locales/fr.json b/frontend/src/shared/i18n/locales/fr.json index 4eadf0521..2df043ab0 100644 --- a/frontend/src/shared/i18n/locales/fr.json +++ b/frontend/src/shared/i18n/locales/fr.json @@ -5428,7 +5428,8 @@ }, "card": { "edit": "Modifier", - "terminate": "Résilier", + "activate": "Activer", + "deactivate": "Désactiver", "deletePermanent": "Supprimer définitivement", "noAccess": "Ce locataire ne vous a pas donné accès.", "loadingStats": "Lecture…", @@ -5464,15 +5465,15 @@ "submit": "Enregistrer" }, "terminate": { - "title": "Résilier ce locataire ?", - "body": "Plus personne chez {{name}} ne pourra se connecter. Les données sont conservées, un opérateur peut donc revenir en arrière, mais le client est hors ligne dès maintenant.", + "title": "Désactiver ce locataire ?", + "body": "Plus personne chez {{name}} ne pourra se connecter. Les données sont conservées, c'est donc réversible, mais le client est hors ligne dès maintenant.", "confirmLabel": "Saisissez {{name}} pour confirmer", - "submit": "Résilier" + "submit": "Désactiver" }, "reactivate": { - "title": "Réactiver ce locataire ?", + "title": "Activer ce locataire ?", "body": "{{name}} pourra se reconnecter. Les données conservées sont restaurées telles quelles.", - "submit": "Réactiver" + "submit": "Activer" }, "deletePermanent": { "title": "Supprimer ce locataire pour toujours ?", diff --git a/frontend/src/shared/i18n/locales/it.json b/frontend/src/shared/i18n/locales/it.json index f774f2693..501372889 100644 --- a/frontend/src/shared/i18n/locales/it.json +++ b/frontend/src/shared/i18n/locales/it.json @@ -5428,7 +5428,8 @@ }, "card": { "edit": "Modifica", - "terminate": "Termina", + "activate": "Attiva", + "deactivate": "Disattiva", "deletePermanent": "Elimina definitivamente", "noAccess": "Questo tenant non ti ha dato accesso.", "loadingStats": "Lettura…", @@ -5464,15 +5465,15 @@ "submit": "Salva modifiche" }, "terminate": { - "title": "Terminare questo tenant?", - "body": "Nessuno in {{name}} potrà più accedere. I dati restano, quindi un operatore può tornare indietro, ma il cliente resta fuori da subito.", + "title": "Disattivare questo tenant?", + "body": "Nessuno in {{name}} potrà più accedere. I dati restano, quindi è reversibile, ma il cliente resta fuori da subito.", "confirmLabel": "Scrivi {{name}} per confermare", - "submit": "Termina" + "submit": "Disattiva" }, "reactivate": { - "title": "Riattivare questo tenant?", + "title": "Attivare questo tenant?", "body": "{{name}} potrà accedere di nuovo. I dati conservati vengono ripristinati così come sono.", - "submit": "Riattiva" + "submit": "Attiva" }, "deletePermanent": { "title": "Eliminare questo tenant per sempre?", diff --git a/frontend/src/shared/i18n/locales/pt.json b/frontend/src/shared/i18n/locales/pt.json index 84a2ad6ba..60595f1fc 100644 --- a/frontend/src/shared/i18n/locales/pt.json +++ b/frontend/src/shared/i18n/locales/pt.json @@ -5390,7 +5390,8 @@ }, "card": { "edit": "Editar", - "terminate": "Encerrar", + "activate": "Ativar", + "deactivate": "Desativar", "deletePermanent": "Excluir permanentemente", "noAccess": "Este tenant não concedeu acesso a você.", "loadingStats": "Lendo…", @@ -5426,15 +5427,15 @@ "submit": "Salvar alterações" }, "terminate": { - "title": "Encerrar este tenant?", - "body": "Ninguém em {{name}} conseguirá entrar. Os dados são mantidos, então um operador pode reverter, mas o cliente fica fora agora.", + "title": "Desativar este tenant?", + "body": "Ninguém em {{name}} conseguirá entrar. Os dados são mantidos, então é reversível, mas o cliente fica fora agora.", "confirmLabel": "Digite {{name}} para confirmar", - "submit": "Encerrar" + "submit": "Desativar" }, "reactivate": { - "title": "Reativar este tenant?", + "title": "Ativar este tenant?", "body": "{{name}} poderá entrar novamente. Os dados preservados são restaurados como estavam.", - "submit": "Reativar" + "submit": "Ativar" }, "deletePermanent": { "title": "Excluir este tenant para sempre?", diff --git a/frontend/src/shared/i18n/locales/ru.json b/frontend/src/shared/i18n/locales/ru.json index 7eb5c3251..586d1fb21 100644 --- a/frontend/src/shared/i18n/locales/ru.json +++ b/frontend/src/shared/i18n/locales/ru.json @@ -5452,7 +5452,8 @@ }, "card": { "edit": "Изменить", - "terminate": "Закрыть", + "activate": "Активировать", + "deactivate": "Деактивировать", "deletePermanent": "Удалить безвозвратно", "noAccess": "Этот арендатор не предоставил вам доступ.", "loadingStats": "Чтение…", @@ -5488,15 +5489,15 @@ "submit": "Сохранить" }, "terminate": { - "title": "Закрыть этого арендатора?", - "body": "Никто из {{name}} не сможет войти. Данные сохраняются, так что оператор может вернуть всё назад, но клиент отключается сейчас.", + "title": "Деактивировать этого арендатора?", + "body": "Никто из {{name}} не сможет войти. Данные сохраняются, так что это обратимо, но клиент отключается сейчас.", "confirmLabel": "Введите {{name}} для подтверждения", - "submit": "Закрыть" + "submit": "Деактивировать" }, "reactivate": { - "title": "Восстановить этого арендатора?", + "title": "Активировать этого арендатора?", "body": "{{name}} снова сможет войти. Сохранённые данные восстанавливаются как есть.", - "submit": "Восстановить" + "submit": "Активировать" }, "deletePermanent": { "title": "Удалить этого арендатора навсегда?",