Delete people in the console, not the webmail's Administration
Deleting a person's account is the console's now, beside locking it and legal holds: the console asks why, for the audit log, and says when a hold keeps the data. Where Delete was, the account's page says so and links to the account in the console when the server names one. Groups, lists, domains and tenants keep their delete here. 2 new strings in all nine catalogs, unreviewed.
This commit is contained in:
1 parent
9e47437ef8
commit
5c08fb9fe9
12 files changed
+60
-63
No files matched your search
@@ -1754,6 +1754,9 @@ export const catalog: Catalog = {
|
|||||||
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
||||||
"Language model's opinion": "Einschätzung des Sprachmodells",
|
"Language model's opinion": "Einschätzung des Sprachmodells",
|
||||||
"One of several signals the spam filter weighed": "Eines von mehreren Signalen, die der Spamfilter berücksichtigt hat",
|
"One of several signals the spam filter weighed": "Eines von mehreren Signalen, die der Spamfilter berücksichtigt hat",
|
||||||
|
// inbuxa: deleting a person is the console's (audit-hold-lock spec)
|
||||||
|
"Deleting, locking and legal holds are done in the administration console, which records why and keeps what a hold covers.": "Löschen, Sperren und rechtliche Aufbewahrungspflichten werden in der Verwaltungskonsole erledigt, die den Grund festhält und bewahrt, was eine Aufbewahrungspflicht umfasst.",
|
||||||
|
"Open in the console": "In der Konsole öffnen",
|
||||||
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
||||||
"You no longer have access to {name}. Back to your own mail.": "Sie haben keinen Zugriff mehr auf {name}. Zurück zu Ihren eigenen E-Mails.",
|
"You no longer have access to {name}. Back to your own mail.": "Sie haben keinen Zugriff mehr auf {name}. Zurück zu Ihren eigenen E-Mails.",
|
||||||
"You can't send from {name}. It was handed to you to read, not to send as.": "Sie können nicht als {name} senden. Das Konto wurde Ihnen zum Lesen übergeben, nicht zum Senden.",
|
"You can't send from {name}. It was handed to you to read, not to send as.": "Sie können nicht als {name} senden. Das Konto wurde Ihnen zum Lesen übergeben, nicht zum Senden.",
|
||||||
|
|||||||
@@ -1727,6 +1727,9 @@ export const catalog: Catalog = {
|
|||||||
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
||||||
"Language model's opinion": "Opinión del modelo de lenguaje",
|
"Language model's opinion": "Opinión del modelo de lenguaje",
|
||||||
"One of several signals the spam filter weighed": "Una de varias señales que el filtro de spam ha tenido en cuenta",
|
"One of several signals the spam filter weighed": "Una de varias señales que el filtro de spam ha tenido en cuenta",
|
||||||
|
// inbuxa: deleting a person is the console's (audit-hold-lock spec)
|
||||||
|
"Deleting, locking and legal holds are done in the administration console, which records why and keeps what a hold covers.": "Eliminar, bloquear y las retenciones legales se gestionan en la consola de administración, que registra el motivo y conserva lo que cubre una retención.",
|
||||||
|
"Open in the console": "Abrir en la consola",
|
||||||
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
||||||
"You no longer have access to {name}. Back to your own mail.": "Ya no tiene acceso a {name}. Vuelve a su propio correo.",
|
"You no longer have access to {name}. Back to your own mail.": "Ya no tiene acceso a {name}. Vuelve a su propio correo.",
|
||||||
"You can't send from {name}. It was handed to you to read, not to send as.": "No puede enviar desde {name}. Se le entregó para leerla, no para enviar en su nombre.",
|
"You can't send from {name}. It was handed to you to read, not to send as.": "No puede enviar desde {name}. Se le entregó para leerla, no para enviar en su nombre.",
|
||||||
|
|||||||
@@ -1732,6 +1732,9 @@ export const catalog: Catalog = {
|
|||||||
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
||||||
"Language model's opinion": "Avis du modèle de langage",
|
"Language model's opinion": "Avis du modèle de langage",
|
||||||
"One of several signals the spam filter weighed": "Un signal parmi d'autres pris en compte par le filtre antispam",
|
"One of several signals the spam filter weighed": "Un signal parmi d'autres pris en compte par le filtre antispam",
|
||||||
|
// inbuxa: deleting a person is the console's (audit-hold-lock spec)
|
||||||
|
"Deleting, locking and legal holds are done in the administration console, which records why and keeps what a hold covers.": "La suppression, le verrouillage et les conservations légales se font dans la console d’administration, qui enregistre le motif et conserve ce qu’une conservation couvre.",
|
||||||
|
"Open in the console": "Ouvrir dans la console",
|
||||||
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
||||||
"You no longer have access to {name}. Back to your own mail.": "Vous n’avez plus accès à {name}. Retour à votre propre courrier.",
|
"You no longer have access to {name}. Back to your own mail.": "Vous n’avez plus accès à {name}. Retour à votre propre courrier.",
|
||||||
"You can't send from {name}. It was handed to you to read, not to send as.": "Vous ne pouvez pas envoyer depuis {name}. Ce compte vous a été confié pour le lire, pas pour envoyer en son nom.",
|
"You can't send from {name}. It was handed to you to read, not to send as.": "Vous ne pouvez pas envoyer depuis {name}. Ce compte vous a été confié pour le lire, pas pour envoyer en son nom.",
|
||||||
|
|||||||
@@ -1735,6 +1735,9 @@ export const catalog: Catalog = {
|
|||||||
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
||||||
"Language model's opinion": "言語モデルの見解",
|
"Language model's opinion": "言語モデルの見解",
|
||||||
"One of several signals the spam filter weighed": "迷惑メールフィルターが考慮した複数の判断材料のひとつ",
|
"One of several signals the spam filter weighed": "迷惑メールフィルターが考慮した複数の判断材料のひとつ",
|
||||||
|
// inbuxa: deleting a person is the console's (audit-hold-lock spec)
|
||||||
|
"Deleting, locking and legal holds are done in the administration console, which records why and keeps what a hold covers.": "削除、ロック、訴訟ホールドは管理コンソールで行います。コンソールでは理由が記録され、ホールドの対象は保持されます。",
|
||||||
|
"Open in the console": "コンソールで開く",
|
||||||
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
||||||
"You no longer have access to {name}. Back to your own mail.": "{name} にアクセスできなくなりました。自分のメールに戻ります。",
|
"You no longer have access to {name}. Back to your own mail.": "{name} にアクセスできなくなりました。自分のメールに戻ります。",
|
||||||
"You can't send from {name}. It was handed to you to read, not to send as.": "{name} から送信することはできません。このアカウントは閲覧のために委任されています。",
|
"You can't send from {name}. It was handed to you to read, not to send as.": "{name} から送信することはできません。このアカウントは閲覧のために委任されています。",
|
||||||
|
|||||||
@@ -1727,6 +1727,9 @@ export const catalog: Catalog = {
|
|||||||
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
||||||
"Language model's opinion": "Oordeel van het taalmodel",
|
"Language model's opinion": "Oordeel van het taalmodel",
|
||||||
"One of several signals the spam filter weighed": "Een van meerdere signalen die het spamfilter heeft meegewogen",
|
"One of several signals the spam filter weighed": "Een van meerdere signalen die het spamfilter heeft meegewogen",
|
||||||
|
// inbuxa: deleting a person is the console's (audit-hold-lock spec)
|
||||||
|
"Deleting, locking and legal holds are done in the administration console, which records why and keeps what a hold covers.": "Verwijderen, vergrendelen en juridische bewaarplichten gebeuren in de beheerconsole, die de reden vastlegt en bewaart wat onder een bewaarplicht valt.",
|
||||||
|
"Open in the console": "Openen in de console",
|
||||||
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
||||||
"You no longer have access to {name}. Back to your own mail.": "U hebt geen toegang meer tot {name}. Terug naar uw eigen mail.",
|
"You no longer have access to {name}. Back to your own mail.": "U hebt geen toegang meer tot {name}. Terug naar uw eigen mail.",
|
||||||
"You can't send from {name}. It was handed to you to read, not to send as.": "U kunt niet verzenden vanuit {name}. Het account is u gegeven om te lezen, niet om namens te verzenden.",
|
"You can't send from {name}. It was handed to you to read, not to send as.": "U kunt niet verzenden vanuit {name}. Het account is u gegeven om te lezen, niet om namens te verzenden.",
|
||||||
|
|||||||
@@ -1730,6 +1730,9 @@ export const catalog: Catalog = {
|
|||||||
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
||||||
"Language model's opinion": "Opinião do modelo de linguagem",
|
"Language model's opinion": "Opinião do modelo de linguagem",
|
||||||
"One of several signals the spam filter weighed": "Um dos vários sinais considerados pelo filtro de spam",
|
"One of several signals the spam filter weighed": "Um dos vários sinais considerados pelo filtro de spam",
|
||||||
|
// inbuxa: deleting a person is the console's (audit-hold-lock spec)
|
||||||
|
"Deleting, locking and legal holds are done in the administration console, which records why and keeps what a hold covers.": "Excluir, bloquear e retenções legais são feitos no console de administração, que registra o motivo e preserva o que uma retenção abrange.",
|
||||||
|
"Open in the console": "Abrir no console",
|
||||||
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
||||||
"You no longer have access to {name}. Back to your own mail.": "Você não tem mais acesso a {name}. De volta ao seu próprio e-mail.",
|
"You no longer have access to {name}. Back to your own mail.": "Você não tem mais acesso a {name}. De volta ao seu próprio e-mail.",
|
||||||
"You can't send from {name}. It was handed to you to read, not to send as.": "Você não pode enviar de {name}. A conta foi entregue a você para leitura, não para enviar em nome dela.",
|
"You can't send from {name}. It was handed to you to read, not to send as.": "Você não pode enviar de {name}. A conta foi entregue a você para leitura, não para enviar em nome dela.",
|
||||||
|
|||||||
@@ -1729,6 +1729,9 @@ export const catalog: Catalog = {
|
|||||||
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
||||||
"Language model's opinion": "Мнение языковой модели",
|
"Language model's opinion": "Мнение языковой модели",
|
||||||
"One of several signals the spam filter weighed": "Один из нескольких признаков, которые учёл спам-фильтр",
|
"One of several signals the spam filter weighed": "Один из нескольких признаков, которые учёл спам-фильтр",
|
||||||
|
// inbuxa: deleting a person is the console's (audit-hold-lock spec)
|
||||||
|
"Deleting, locking and legal holds are done in the administration console, which records why and keeps what a hold covers.": "Удаление, блокировка и юридическое удержание выполняются в консоли администрирования: она записывает причину и сохраняет всё, что охватывает удержание.",
|
||||||
|
"Open in the console": "Открыть в консоли",
|
||||||
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
||||||
"You no longer have access to {name}. Back to your own mail.": "У вас больше нет доступа к {name}. Возвращаемся к вашей почте.",
|
"You no longer have access to {name}. Back to your own mail.": "У вас больше нет доступа к {name}. Возвращаемся к вашей почте.",
|
||||||
"You can't send from {name}. It was handed to you to read, not to send as.": "Вы не можете отправлять письма от имени {name}. Учётная запись передана вам для чтения, а не для отправки.",
|
"You can't send from {name}. It was handed to you to read, not to send as.": "Вы не можете отправлять письма от имени {name}. Учётная запись передана вам для чтения, а не для отправки.",
|
||||||
|
|||||||
@@ -1723,6 +1723,9 @@ export const catalog: Catalog = {
|
|||||||
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
||||||
"Language model's opinion": "Думка мовної моделі",
|
"Language model's opinion": "Думка мовної моделі",
|
||||||
"One of several signals the spam filter weighed": "Одна з кількох ознак, які врахував спам-фільтр",
|
"One of several signals the spam filter weighed": "Одна з кількох ознак, які врахував спам-фільтр",
|
||||||
|
// inbuxa: deleting a person is the console's (audit-hold-lock spec)
|
||||||
|
"Deleting, locking and legal holds are done in the administration console, which records why and keeps what a hold covers.": "Видалення, блокування та юридичне утримання виконуються в консолі адміністрування: вона записує причину й зберігає все, що охоплює утримання.",
|
||||||
|
"Open in the console": "Відкрити в консолі",
|
||||||
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
||||||
"You no longer have access to {name}. Back to your own mail.": "У вас більше немає доступу до {name}. Повертаємося до вашої пошти.",
|
"You no longer have access to {name}. Back to your own mail.": "У вас більше немає доступу до {name}. Повертаємося до вашої пошти.",
|
||||||
"You can't send from {name}. It was handed to you to read, not to send as.": "Ви не можете надсилати листи від імені {name}. Обліковий запис передано вам для читання, а не для надсилання.",
|
"You can't send from {name}. It was handed to you to read, not to send as.": "Ви не можете надсилати листи від імені {name}. Обліковий запис передано вам для читання, а не для надсилання.",
|
||||||
|
|||||||
@@ -1734,6 +1734,9 @@ export const catalog: Catalog = {
|
|||||||
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
// ── Spam filter: the language model's opinion (inbuxa) ──────────
|
||||||
"Language model's opinion": "语言模型的判断",
|
"Language model's opinion": "语言模型的判断",
|
||||||
"One of several signals the spam filter weighed": "垃圾邮件过滤考虑的多个信号之一",
|
"One of several signals the spam filter weighed": "垃圾邮件过滤考虑的多个信号之一",
|
||||||
|
// inbuxa: deleting a person is the console's (audit-hold-lock spec)
|
||||||
|
"Deleting, locking and legal holds are done in the administration console, which records why and keeps what a hold covers.": "删除、锁定和法律保留均在管理控制台中进行,控制台会记录原因,并保留保留范围内的内容。",
|
||||||
|
"Open in the console": "在控制台中打开",
|
||||||
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
// inbuxa AL-7, AL-8: a locked account handed to the reader
|
||||||
"You no longer have access to {name}. Back to your own mail.": "您已无法访问 {name}。已返回您自己的邮件。",
|
"You no longer have access to {name}. Back to your own mail.": "您已无法访问 {name}。已返回您自己的邮件。",
|
||||||
"You can't send from {name}. It was handed to you to read, not to send as.": "您不能从 {name} 发送邮件。该账户交给您是为了阅读,而不是代其发送。",
|
"You can't send from {name}. It was handed to you to read, not to send as.": "您不能从 {name} 发送邮件。该账户交给您是为了阅读,而不是代其发送。",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { Copy, Dices, KeyRound, Lock, Plus, Trash2, X } from "lucide-react";
|
import { Copy, Dices, ExternalLink, KeyRound, Lock, Plus, X } from "lucide-react";
|
||||||
import {
|
import {
|
||||||
ADMIN_BASELINE,
|
ADMIN_BASELINE,
|
||||||
can,
|
can,
|
||||||
@@ -12,7 +12,6 @@ import {
|
|||||||
aliasList,
|
aliasList,
|
||||||
createAccount,
|
createAccount,
|
||||||
describeDirectoryError,
|
describeDirectoryError,
|
||||||
destroyAccount,
|
|
||||||
hasPassword,
|
hasPassword,
|
||||||
passwordPatch,
|
passwordPatch,
|
||||||
quotasWithDisk,
|
quotasWithDisk,
|
||||||
@@ -25,7 +24,7 @@ import { formatSize } from "@/lib/format";
|
|||||||
import { t, tNode } from "@/lib/i18n";
|
import { t, tNode } from "@/lib/i18n";
|
||||||
import { Link } from "wouter";
|
import { Link } from "wouter";
|
||||||
import { Avatar } from "@/ui/misc";
|
import { Avatar } from "@/ui/misc";
|
||||||
import { Dialog } from "@/ui/dialog";
|
import { useSession } from "@/store/session";
|
||||||
import { toast } from "@/ui/toast";
|
import { toast } from "@/ui/toast";
|
||||||
import { isSelf, roleName, type DirectoryContext } from "./directoryContext";
|
import { isSelf, roleName, type DirectoryContext } from "./directoryContext";
|
||||||
import { usePermissions } from "./usePermissions";
|
import { usePermissions } from "./usePermissions";
|
||||||
@@ -39,7 +38,6 @@ interface Props {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onChanged: () => void;
|
onChanged: () => void;
|
||||||
onCreated: (id: string) => void;
|
onCreated: (id: string) => void;
|
||||||
onDeleted: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A role as one select value: "User", "Admin", or "custom:<ids>". */
|
/** A role as one select value: "User", "Admin", or "custom:<ids>". */
|
||||||
@@ -71,7 +69,7 @@ const bytesOf = (gib: string) => {
|
|||||||
* a password and a delete are their own calls, because each is a decision of
|
* a password and a delete are their own calls, because each is a decision of
|
||||||
* its own and should never ride along with a renamed display name.
|
* its own and should never ride along with a renamed display name.
|
||||||
*/
|
*/
|
||||||
export function AccountSheet({ account, ctx, onClose, onChanged, onCreated, onDeleted }: Props) {
|
export function AccountSheet({ account, ctx, onClose, onChanged, onCreated }: Props) {
|
||||||
const perms = usePermissions();
|
const perms = usePermissions();
|
||||||
const creating = account === null;
|
const creating = account === null;
|
||||||
const self = account ? isSelf(account, ctx) : false;
|
const self = account ? isSelf(account, ctx) : false;
|
||||||
@@ -288,9 +286,7 @@ export function AccountSheet({ account, ctx, onClose, onChanged, onCreated, onDe
|
|||||||
|
|
||||||
{error && <p className="admin-notice error" role="alert">{error}</p>}
|
{error && <p className="admin-notice error" role="alert">{error}</p>}
|
||||||
|
|
||||||
{!creating && can(perms, "Account", "Destroy") && (
|
{!creating && can(perms, "Account", "Destroy") && <DeleteInConsole accountId={account.id} />}
|
||||||
<DeleteAccount account={account} blocked={self ? t("You can't delete the account you're signed in with.") : locked ? t("This account has permissions yours doesn't.") : null} onDeleted={onDeleted} />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{editable && (
|
{editable && (
|
||||||
@@ -433,59 +429,24 @@ export function Aliases({ aliases, setAliases, editable, domains, defaultDomain,
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function DeleteAccount({ account, blocked, onDeleted }: { account: DirectoryAccount; blocked: string | null; onDeleted: () => void }) {
|
/**
|
||||||
const [open, setOpen] = useState(false);
|
* inbuxa: deleting a person's account is the console's, beside locking it
|
||||||
const [typed, setTyped] = useState("");
|
* and legal holds: it asks why, for the audit log, and says when a hold
|
||||||
const [busy, setBusy] = useState(false);
|
* keeps the data. Only the pointer is here.
|
||||||
const [error, setError] = useState<string | null>(null);
|
*/
|
||||||
const address = account.emailAddress ?? account.name;
|
function DeleteInConsole({ accountId }: { accountId: string }) {
|
||||||
|
const adminUrl = useSession((s) => s.session?.ihasmail?.server?.adminUrl ?? null);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3>{t("Delete")}</h3>
|
<h3>{t("Delete")}</h3>
|
||||||
<div className="admin-danger">
|
<div className="admin-danger">
|
||||||
<p>{blocked ?? t("Deletes the mailbox and everything in it.")}</p>
|
<p>{t("Deleting, locking and legal holds are done in the administration console, which records why and keeps what a hold covers.")}</p>
|
||||||
<button className="btn btn-sm admin-danger-btn" disabled={!!blocked} onClick={() => { setTyped(""); setError(null); setOpen(true); }}>
|
{adminUrl && (
|
||||||
<Trash2 size={14} /> {t("Delete account…")}
|
<a className="btn btn-sm" href={`${adminUrl.replace(/\/$/, "")}/Management/x:Account/User/${accountId}`} target="_blank" rel="noopener noreferrer">
|
||||||
</button>
|
<ExternalLink size={14} /> {t("Open in the console")}
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Dialog
|
|
||||||
open={open}
|
|
||||||
onClose={() => setOpen(false)}
|
|
||||||
title={t("Delete {address}?", { address })}
|
|
||||||
size="sm"
|
|
||||||
footer={
|
|
||||||
<>
|
|
||||||
<button className="btn" onClick={() => setOpen(false)}>{t("Cancel")}</button>
|
|
||||||
<button
|
|
||||||
className="btn btn-danger"
|
|
||||||
disabled={busy || typed.trim().toLowerCase() !== address.toLowerCase()}
|
|
||||||
onClick={async () => {
|
|
||||||
setBusy(true);
|
|
||||||
setError(null);
|
|
||||||
try {
|
|
||||||
await destroyAccount(account.id);
|
|
||||||
toast.success(t("Deleted {address}", { address }));
|
|
||||||
setOpen(false);
|
|
||||||
onDeleted();
|
|
||||||
} catch (err) {
|
|
||||||
setError(describeDirectoryError(err));
|
|
||||||
} finally {
|
|
||||||
setBusy(false);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t("Delete account")}
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<p style={{ marginTop: 0 }}>{t("This deletes the mail, calendars, contacts and files in this account. The server removes them in the background, and it can't be undone.")}</p>
|
|
||||||
<div className="field">
|
|
||||||
<label htmlFor="admin-delete-confirm">{t("Type {address} to confirm", { address })}</label>
|
|
||||||
<input id="admin-delete-confirm" className="input notranslate" translate="no" value={typed} autoComplete="off" spellCheck={false} onChange={(e) => setTyped(e.target.value)} />
|
|
||||||
</div>
|
|
||||||
{error && <p className="admin-notice error" role="alert">{error}</p>}
|
|
||||||
</Dialog>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -217,10 +217,6 @@ export function AccountsAdmin({ selectedId }: { selectedId?: string }) {
|
|||||||
changed();
|
changed();
|
||||||
navigate(`/admin/accounts/${id}`);
|
navigate(`/admin/accounts/${id}`);
|
||||||
}}
|
}}
|
||||||
onDeleted={() => {
|
|
||||||
changed();
|
|
||||||
close();
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ describe("the account sheet", () => {
|
|||||||
await act(async () => {
|
await act(async () => {
|
||||||
root.render(
|
root.render(
|
||||||
<Router hook={hook}>
|
<Router hook={hook}>
|
||||||
<AccountSheet account={a} ctx={ctx} onClose={() => {}} onChanged={() => {}} onCreated={() => {}} onDeleted={() => {}} />
|
<AccountSheet account={a} ctx={ctx} onClose={() => {}} onChanged={() => {}} onCreated={() => {}} />
|
||||||
</Router>,
|
</Router>,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -89,7 +89,20 @@ describe("the account sheet", () => {
|
|||||||
expect(host.querySelector('a[href="/settings/security"]')).not.toBeNull();
|
expect(host.querySelector('a[href="/settings/security"]')).not.toBeNull();
|
||||||
expect(button(host, "Set a new password")).toBeUndefined();
|
expect(button(host, "Set a new password")).toBeUndefined();
|
||||||
expect((host.querySelector('select[aria-label="Role"]') as HTMLSelectElement).disabled).toBe(true);
|
expect((host.querySelector('select[aria-label="Role"]') as HTMLSelectElement).disabled).toBe(true);
|
||||||
expect(button(host, "Delete account")?.disabled).toBe(true);
|
expect(host.textContent).not.toContain("Delete account");
|
||||||
|
expect(host.textContent).toContain("administration console");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sends deleting a person to the console, opened on that account (inbuxa)", async () => {
|
||||||
|
signIn([...HELPDESK, "sysAccountDestroy"]);
|
||||||
|
const s = useSession.getState().session!;
|
||||||
|
useSession.setState({
|
||||||
|
session: { ...s, ihasmail: { ...s.ihasmail, server: { ...(s.ihasmail?.server ?? {}), adminUrl: "https://admin.example.com/" } } } as never,
|
||||||
|
});
|
||||||
|
await render(account({ id: "k7" }));
|
||||||
|
expect(host.textContent).not.toContain("Delete account");
|
||||||
|
const link = host.querySelector('a[href="https://admin.example.com/Management/x:Account/User/k7"]');
|
||||||
|
expect(link?.textContent).toContain("Open in the console");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -108,7 +121,7 @@ describe("an account's tenant", () => {
|
|||||||
const render = async (a: DirectoryAccount) => {
|
const render = async (a: DirectoryAccount) => {
|
||||||
const { hook } = memoryLocation({ path: `/admin/accounts/${a.id}` });
|
const { hook } = memoryLocation({ path: `/admin/accounts/${a.id}` });
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
root.render(<Router hook={hook}><AccountSheet account={a} ctx={tenantCtx} onClose={() => {}} onChanged={() => {}} onCreated={() => {}} onDeleted={() => {}} /></Router>);
|
root.render(<Router hook={hook}><AccountSheet account={a} ctx={tenantCtx} onClose={() => {}} onChanged={() => {}} onCreated={() => {}} /></Router>);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
Reference in new issue
Block a user