Skip to content

Commit 36fd383

Browse files
Backlog/v12 tenant cards options (#2487)
* feat[frontend](tenants): moved activate/deactivate from edit dialog to card * fix[frontend](tenants): added missing language keys
1 parent ae423a8 commit 36fd383

10 files changed

Lines changed: 90 additions & 104 deletions

File tree

‎frontend/src/features/tenants/components/EditTenantDialog.tsx‎

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@ import { cn } from '@/shared/lib/utils'
66
import { Button } from '@/shared/components/ui/button'
77
import { Input } from '@/shared/components/ui/input'
88
import { tenantsHttpService } from '../services/tenants-http.service'
9-
import type { Tenant, TenantStatus } from '../types/tenant.types'
9+
import type { Tenant } from '../types/tenant.types'
1010
import { Modal } from './Modal'
1111
import { Field } from './Field'
1212
import { tenantError } from './tenant-error'
13-
import { ReactivateTenantDialog } from './ReactivateTenantDialog'
14-
15-
const STATUSES: TenantStatus[] = ['ACTIVE', 'SUSPENDED']
1613

1714
export function EditTenantDialog({
1815
tenant,
@@ -22,27 +19,10 @@ export function EditTenantDialog({
2219
tenant: Tenant
2320
onClose: () => void
2421
onSaved: () => void
25-
}) {
26-
if (tenant.status === 'TERMINATED') {
27-
return <ReactivateTenantDialog tenant={tenant} onClose={onClose} onSaved={onSaved} />
28-
}
29-
30-
return <EditTenantForm tenant={tenant} onClose={onClose} onSaved={onSaved} />
31-
}
32-
33-
function EditTenantForm({
34-
tenant,
35-
onClose,
36-
onSaved,
37-
}: {
38-
tenant: Tenant
39-
onClose: () => void
40-
onSaved: () => void
4122
}) {
4223
const { t } = useTranslation()
4324
const [name, setName] = useState(tenant.name)
4425
const [domain, setDomain] = useState(tenant.domain)
45-
const [status, setStatus] = useState<TenantStatus>(tenant.status)
4626
const [capped, setCapped] = useState(tenant.limits.maxAIRequests != null)
4727
const [maxAI, setMaxAI] = useState(String(tenant.limits.maxAIRequests ?? ''))
4828
const [busy, setBusy] = useState(false)
@@ -58,7 +38,6 @@ function EditTenantForm({
5838
await tenantsHttpService.update(tenant.id, {
5939
name: name.trim(),
6040
domain: domain.trim().toLowerCase(),
61-
status,
6241
// Clearing the cap sends an explicit null: omitting the field would
6342
// mean "leave it as it is", which is the opposite of the intent.
6443
maxAIRequests: capped ? parsedMax : null,
@@ -96,29 +75,6 @@ function EditTenantForm({
9675
<Input value={domain} onChange={(e) => setDomain(e.target.value)} className="font-mono" />
9776
</Field>
9877

99-
<Field label={t('tenants.fields.status')}>
100-
<div className="flex gap-2">
101-
{STATUSES.map((s) => (
102-
<button
103-
key={s}
104-
type="button"
105-
onClick={() => setStatus(s)}
106-
className={cn(
107-
'flex-1 rounded-md border px-3 py-2 text-xs font-medium transition-colors',
108-
status === s ? 'border-primary/40 bg-primary/5 text-foreground' : 'border-border text-muted-foreground hover:bg-muted/40'
109-
)}
110-
>
111-
{t(`tenants.status.${s}`, { defaultValue: s })}
112-
</button>
113-
))}
114-
</div>
115-
{status === 'SUSPENDED' && (
116-
<p className="text-[11px] text-amber-600 dark:text-amber-300">
117-
{t('tenants.fields.suspendedWarning')}
118-
</p>
119-
)}
120-
</Field>
121-
12278
<Field label={t('tenants.fields.aiLimit')} hint={t('tenants.fields.aiLimitHint')}>
12379
<button
12480
type="button"

‎frontend/src/features/tenants/components/TenantCard.tsx‎

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,15 @@ export function TenantCard({
161161
tenant,
162162
readable,
163163
onEdit,
164-
onTerminate,
164+
onActivate,
165+
onDeactivate,
165166
onDelete,
166167
}: {
167168
tenant: Tenant
168169
readable: boolean
169170
onEdit: () => void
170-
onTerminate: () => void
171+
onActivate: () => void
172+
onDeactivate: () => void
171173
onDelete: () => void
172174
}) {
173175
const { t } = useTranslation()
@@ -244,25 +246,33 @@ export function TenantCard({
244246
>
245247
<Pencil size={13} />
246248
</button>
247-
{!terminated ? (
249+
{tenant.status === 'ACTIVE' ? (
248250
<button
249251
type="button"
250-
onClick={onTerminate}
251-
title={t('tenants.card.terminate')}
252-
className="flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-red-500/10 hover:text-red-500"
252+
onClick={onDeactivate}
253+
title={t('tenants.card.deactivate')}
254+
className="flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-amber-500/10 hover:text-amber-600"
253255
>
254-
<Trash2 size={13} />
256+
<Power size={13} />
255257
</button>
256258
) : (
257259
<button
258260
type="button"
259-
onClick={onDelete}
260-
title={t('tenants.card.deletePermanent')}
261-
className="flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground"
261+
onClick={onActivate}
262+
title={t('tenants.card.activate')}
263+
className="flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-emerald-500/10 hover:text-emerald-600"
262264
>
263-
<Trash2 size={13} />
265+
<Power size={13} />
264266
</button>
265267
)}
268+
<button
269+
type="button"
270+
onClick={onDelete}
271+
title={t('tenants.card.deletePermanent')}
272+
className="flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground"
273+
>
274+
<Trash2 size={13} />
275+
</button>
266276
</div>
267277
</div>
268278

‎frontend/src/features/tenants/pages/TenantsPage.tsx‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { TenantCard } from '../components/TenantCard'
2020
import { CreateTenantDialog } from '../components/CreateTenantDialog'
2121
import { EditTenantDialog } from '../components/EditTenantDialog'
2222
import { TerminateDialog } from '../components/TerminateDialog'
23+
import { ReactivateTenantDialog } from '../components/ReactivateTenantDialog'
2324
import { PermanentDeleteDialog } from '../components/PermanentDeleteDialog'
2425

2526
/* ─────────────────────────────────────────────────────────────────────────
@@ -34,7 +35,8 @@ export function TenantsPage() {
3435
const [query, setQuery] = useState('')
3536
const [creating, setCreating] = useState(false)
3637
const [editing, setEditing] = useState<Tenant | null>(null)
37-
const [terminating, setTerminating] = useState<Tenant | null>(null)
38+
const [deactivating, setDeactivating] = useState<Tenant | null>(null)
39+
const [activating, setActivating] = useState<Tenant | null>(null)
3840
const [deletingPermanently, setDeletingPermanently] = useState<Tenant | null>(null)
3941

4042
const load = useCallback(async () => {
@@ -128,7 +130,8 @@ export function TenantsPage() {
128130
tenant={tenant}
129131
readable={canReadTenant(tenant)}
130132
onEdit={() => setEditing(tenant)}
131-
onTerminate={() => setTerminating(tenant)}
133+
onActivate={() => setActivating(tenant)}
134+
onDeactivate={() => setDeactivating(tenant)}
132135
onDelete={() => setDeletingPermanently(tenant)}
133136
/>
134137
))}
@@ -157,12 +160,22 @@ export function TenantsPage() {
157160
}}
158161
/>
159162
)}
160-
{terminating && (
163+
{deactivating && (
161164
<TerminateDialog
162-
tenant={terminating}
163-
onClose={() => setTerminating(null)}
165+
tenant={deactivating}
166+
onClose={() => setDeactivating(null)}
164167
onDone={() => {
165-
setTerminating(null)
168+
setDeactivating(null)
169+
void load()
170+
}}
171+
/>
172+
)}
173+
{activating && (
174+
<ReactivateTenantDialog
175+
tenant={activating}
176+
onClose={() => setActivating(null)}
177+
onSaved={() => {
178+
setActivating(null)
166179
void load()
167180
}}
168181
/>

‎frontend/src/shared/i18n/locales/de.json‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5428,7 +5428,8 @@
54285428
},
54295429
"card": {
54305430
"edit": "Bearbeiten",
5431-
"terminate": "Beenden",
5431+
"activate": "Aktivieren",
5432+
"deactivate": "Deaktivieren",
54325433
"deletePermanent": "Endgültig löschen",
54335434
"noAccess": "Dieser Mandant hat Ihnen keinen Zugriff gewährt.",
54345435
"loadingStats": "Wird gelesen…",
@@ -5464,15 +5465,15 @@
54645465
"submit": "Änderungen speichern"
54655466
},
54665467
"terminate": {
5467-
"title": "Diesen Mandanten beenden?",
5468-
"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.",
5468+
"title": "Diesen Mandanten deaktivieren?",
5469+
"body": "Niemand aus {{name}} kann sich mehr anmelden. Die Daten bleiben erhalten, es ist also umkehrbar — aber der Kunde ist ab sofort offline.",
54695470
"confirmLabel": "Zum Bestätigen {{name}} eingeben",
5470-
"submit": "Beenden"
5471+
"submit": "Deaktivieren"
54715472
},
54725473
"reactivate": {
5473-
"title": "Diesen Mandanten reaktivieren?",
5474+
"title": "Diesen Mandanten aktivieren?",
54745475
"body": "{{name}} kann sich wieder anmelden. Die aufbewahrten Daten werden unverändert wiederhergestellt.",
5475-
"submit": "Reaktivieren"
5476+
"submit": "Aktivieren"
54765477
},
54775478
"deletePermanent": {
54785479
"title": "Diesen Mandanten für immer löschen?",

‎frontend/src/shared/i18n/locales/en.json‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5408,7 +5408,8 @@
54085408
},
54095409
"card": {
54105410
"edit": "Edit",
5411-
"terminate": "Terminate",
5411+
"activate": "Activate",
5412+
"deactivate": "Deactivate",
54125413
"deletePermanent": "Delete permanently",
54135414
"noAccess": "This tenant has not granted you access.",
54145415
"loadingStats": "Reading…",
@@ -5444,15 +5445,15 @@
54445445
"submit": "Save changes"
54455446
},
54465447
"terminate": {
5447-
"title": "Terminate this tenant?",
5448-
"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.",
5448+
"title": "Deactivate this tenant?",
5449+
"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.",
54495450
"confirmLabel": "Type {{name}} to confirm",
5450-
"submit": "Terminate"
5451+
"submit": "Deactivate"
54515452
},
54525453
"reactivate": {
5453-
"title": "Reactivate this tenant?",
5454+
"title": "Activate this tenant?",
54545455
"body": "{{name}} will be able to sign in again. Their preserved data is restored as-is.",
5455-
"submit": "Reactivate"
5456+
"submit": "Activate"
54565457
},
54575458
"deletePermanent": {
54585459
"title": "Delete this tenant forever?",

‎frontend/src/shared/i18n/locales/es.json‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5390,7 +5390,8 @@
53905390
},
53915391
"card": {
53925392
"edit": "Editar",
5393-
"terminate": "Terminar",
5393+
"activate": "Activar",
5394+
"deactivate": "Desactivar",
53945395
"deletePermanent": "Eliminar permanentemente",
53955396
"noAccess": "Este tenant no te ha dado acceso.",
53965397
"loadingStats": "Leyendo…",
@@ -5426,15 +5427,15 @@
54265427
"submit": "Guardar cambios"
54275428
},
54285429
"terminate": {
5429-
"title": "¿Terminar este tenant?",
5430-
"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.",
5430+
"title": "¿Desactivar este tenant?",
5431+
"body": "Nadie de {{name}} podrá iniciar sesión. Sus datos se conservan, así que es reversible, pero deja al cliente fuera ahora mismo.",
54315432
"confirmLabel": "Escribe {{name}} para confirmar",
5432-
"submit": "Terminar"
5433+
"submit": "Desactivar"
54335434
},
54345435
"reactivate": {
5435-
"title": "¿Reactivar este tenant?",
5436+
"title": "¿Activar este tenant?",
54365437
"body": "{{name}} podrá iniciar sesión de nuevo. Sus datos conservados se restauran tal cual.",
5437-
"submit": "Reactivar"
5438+
"submit": "Activar"
54385439
},
54395440
"deletePermanent": {
54405441
"title": "¿Eliminar este tenant para siempre?",

‎frontend/src/shared/i18n/locales/fr.json‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5428,7 +5428,8 @@
54285428
},
54295429
"card": {
54305430
"edit": "Modifier",
5431-
"terminate": "Résilier",
5431+
"activate": "Activer",
5432+
"deactivate": "Désactiver",
54325433
"deletePermanent": "Supprimer définitivement",
54335434
"noAccess": "Ce locataire ne vous a pas donné accès.",
54345435
"loadingStats": "Lecture…",
@@ -5464,15 +5465,15 @@
54645465
"submit": "Enregistrer"
54655466
},
54665467
"terminate": {
5467-
"title": "Résilier ce locataire ?",
5468-
"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.",
5468+
"title": "Désactiver ce locataire ?",
5469+
"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.",
54695470
"confirmLabel": "Saisissez {{name}} pour confirmer",
5470-
"submit": "Résilier"
5471+
"submit": "Désactiver"
54715472
},
54725473
"reactivate": {
5473-
"title": "Réactiver ce locataire ?",
5474+
"title": "Activer ce locataire ?",
54745475
"body": "{{name}} pourra se reconnecter. Les données conservées sont restaurées telles quelles.",
5475-
"submit": "Réactiver"
5476+
"submit": "Activer"
54765477
},
54775478
"deletePermanent": {
54785479
"title": "Supprimer ce locataire pour toujours ?",

‎frontend/src/shared/i18n/locales/it.json‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5428,7 +5428,8 @@
54285428
},
54295429
"card": {
54305430
"edit": "Modifica",
5431-
"terminate": "Termina",
5431+
"activate": "Attiva",
5432+
"deactivate": "Disattiva",
54325433
"deletePermanent": "Elimina definitivamente",
54335434
"noAccess": "Questo tenant non ti ha dato accesso.",
54345435
"loadingStats": "Lettura…",
@@ -5464,15 +5465,15 @@
54645465
"submit": "Salva modifiche"
54655466
},
54665467
"terminate": {
5467-
"title": "Terminare questo tenant?",
5468-
"body": "Nessuno in {{name}} potrà più accedere. I dati restano, quindi un operatore può tornare indietro, ma il cliente resta fuori da subito.",
5468+
"title": "Disattivare questo tenant?",
5469+
"body": "Nessuno in {{name}} potrà più accedere. I dati restano, quindi è reversibile, ma il cliente resta fuori da subito.",
54695470
"confirmLabel": "Scrivi {{name}} per confermare",
5470-
"submit": "Termina"
5471+
"submit": "Disattiva"
54715472
},
54725473
"reactivate": {
5473-
"title": "Riattivare questo tenant?",
5474+
"title": "Attivare questo tenant?",
54745475
"body": "{{name}} potrà accedere di nuovo. I dati conservati vengono ripristinati così come sono.",
5475-
"submit": "Riattiva"
5476+
"submit": "Attiva"
54765477
},
54775478
"deletePermanent": {
54785479
"title": "Eliminare questo tenant per sempre?",

‎frontend/src/shared/i18n/locales/pt.json‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5390,7 +5390,8 @@
53905390
},
53915391
"card": {
53925392
"edit": "Editar",
5393-
"terminate": "Encerrar",
5393+
"activate": "Ativar",
5394+
"deactivate": "Desativar",
53945395
"deletePermanent": "Excluir permanentemente",
53955396
"noAccess": "Este tenant não concedeu acesso a você.",
53965397
"loadingStats": "Lendo…",
@@ -5426,15 +5427,15 @@
54265427
"submit": "Salvar alterações"
54275428
},
54285429
"terminate": {
5429-
"title": "Encerrar este tenant?",
5430-
"body": "Ninguém em {{name}} conseguirá entrar. Os dados são mantidos, então um operador pode reverter, mas o cliente fica fora agora.",
5430+
"title": "Desativar este tenant?",
5431+
"body": "Ninguém em {{name}} conseguirá entrar. Os dados são mantidos, então é reversível, mas o cliente fica fora agora.",
54315432
"confirmLabel": "Digite {{name}} para confirmar",
5432-
"submit": "Encerrar"
5433+
"submit": "Desativar"
54335434
},
54345435
"reactivate": {
5435-
"title": "Reativar este tenant?",
5436+
"title": "Ativar este tenant?",
54365437
"body": "{{name}} poderá entrar novamente. Os dados preservados são restaurados como estavam.",
5437-
"submit": "Reativar"
5438+
"submit": "Ativar"
54385439
},
54395440
"deletePermanent": {
54405441
"title": "Excluir este tenant para sempre?",

0 commit comments

Comments
 (0)