mirror of
https://github.com/rustfs/console.git
synced 2026-08-30 17:14:47 +08:00
fix(access-keys): show framed, per-field, localized create errors (#137)
This commit is contained in:
committed by
GitHub
parent
8e3161e0e7
commit
55079b713e
@@ -37,6 +37,7 @@ export function AccessKeysNewItem({ visible, onVisibleChange, onSuccess, onNotic
|
||||
const [policy, setPolicy] = React.useState("")
|
||||
const [impliedPolicy, setImpliedPolicy] = React.useState(true)
|
||||
const [submitting, setSubmitting] = React.useState(false)
|
||||
const [submitError, setSubmitError] = React.useState("")
|
||||
const [errors, setErrors] = React.useState({
|
||||
accessKey: "",
|
||||
secretKey: "",
|
||||
@@ -60,6 +61,7 @@ export function AccessKeysNewItem({ visible, onVisibleChange, onSuccess, onNotic
|
||||
setExpiry(null)
|
||||
setImpliedPolicy(true)
|
||||
setErrors({ accessKey: "", secretKey: "", name: "" })
|
||||
setSubmitError("")
|
||||
api
|
||||
.get("/accountinfo")
|
||||
.then((userInfo: { policy?: unknown; Policy?: unknown }) => {
|
||||
@@ -92,6 +94,8 @@ export function AccessKeysNewItem({ visible, onVisibleChange, onSuccess, onNotic
|
||||
newErrors.accessKey = t("Please enter Access Key")
|
||||
} else if (accessKey.length < 3 || accessKey.length > 20) {
|
||||
newErrors.accessKey = t("Access Key length must be between 3 and 20 characters")
|
||||
} else if (/\s/.test(accessKey)) {
|
||||
newErrors.accessKey = t("Access Key cannot contain spaces")
|
||||
}
|
||||
if (!secretKey) {
|
||||
newErrors.secretKey = t("Please enter Secret Key")
|
||||
@@ -100,12 +104,42 @@ export function AccessKeysNewItem({ visible, onVisibleChange, onSuccess, onNotic
|
||||
}
|
||||
if (!name) {
|
||||
newErrors.name = t("Please enter name")
|
||||
} else if (name.length > 32) {
|
||||
newErrors.name = t("Name must be at most 32 characters")
|
||||
} else if (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(name)) {
|
||||
newErrors.name = t(
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter",
|
||||
)
|
||||
}
|
||||
setErrors(newErrors)
|
||||
return !newErrors.accessKey && !newErrors.secretKey && !newErrors.name
|
||||
}
|
||||
|
||||
// Map a server-side validation error to the field it belongs to, so the
|
||||
// message renders directly under the relevant input. Returns false when the
|
||||
// error is not field-specific (caller falls back to a general message).
|
||||
const applyServerError = (reason: string): boolean => {
|
||||
const lowered = reason.toLowerCase()
|
||||
if (lowered.includes("access key") && lowered.includes("space")) {
|
||||
setErrors((prev) => ({ ...prev, accessKey: t("Access Key cannot contain spaces") }))
|
||||
return true
|
||||
}
|
||||
if (lowered.includes("name must contain only") || lowered.includes("name must start")) {
|
||||
setErrors((prev) => ({
|
||||
...prev,
|
||||
name: t("Name can only contain letters, numbers, underscores and hyphens, and must start with a letter"),
|
||||
}))
|
||||
return true
|
||||
}
|
||||
if (lowered.includes("name must not be longer") || lowered.includes("name is too long")) {
|
||||
setErrors((prev) => ({ ...prev, name: t("Name must be at most 32 characters") }))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const submitForm = async () => {
|
||||
setSubmitError("")
|
||||
if (!validate()) {
|
||||
message.error(t("Please fill in the correct format"))
|
||||
return
|
||||
@@ -140,7 +174,12 @@ export function AccessKeysNewItem({ visible, onVisibleChange, onSuccess, onNotic
|
||||
onSuccess()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
message.error(t("Add failed"))
|
||||
const reason = error instanceof Error && error.message ? error.message : ""
|
||||
const handledByField = reason ? applyServerError(reason) : false
|
||||
if (!handledByField) {
|
||||
setSubmitError(reason || t("Add failed"))
|
||||
}
|
||||
message.error(reason || t("Add failed"))
|
||||
} finally {
|
||||
setSubmitting(false)
|
||||
}
|
||||
@@ -273,6 +312,12 @@ export function AccessKeysNewItem({ visible, onVisibleChange, onSuccess, onNotic
|
||||
)}
|
||||
</div>
|
||||
|
||||
{submitError && (
|
||||
<p role="alert" className="px-2 text-sm text-destructive">
|
||||
{submitError}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<DialogFooter className="border-t pt-4">
|
||||
<Button variant="outline" onClick={closeModal}>
|
||||
{t("Cancel")}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "جار تحضير التنزيل",
|
||||
"User menu": "قائمة المستخدم",
|
||||
"Cleanup Warnings": "تحذيرات التنظيف",
|
||||
"Failed to load objects": "فشل تحميل الكائنات"
|
||||
"Failed to load objects": "فشل تحميل الكائنات",
|
||||
"Access Key cannot contain spaces": "لا يمكن أن يحتوي مفتاح الوصول على مسافات",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "يمكن أن يحتوي الاسم على أحرف وأرقام وشرطات سفلية وشرطات فقط، ويجب أن يبدأ بحرف",
|
||||
"Name must be at most 32 characters": "يجب ألا يزيد الاسم عن 32 حرفًا"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "Download wird vorbereitet",
|
||||
"User menu": "Benutzermenü",
|
||||
"Cleanup Warnings": "Bereinigungswarnungen",
|
||||
"Failed to load objects": "Objekte konnten nicht geladen werden"
|
||||
"Failed to load objects": "Objekte konnten nicht geladen werden",
|
||||
"Access Key cannot contain spaces": "Der Zugriffsschlüssel darf keine Leerzeichen enthalten",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "Der Name darf nur Buchstaben, Ziffern, Unterstriche und Bindestriche enthalten und muss mit einem Buchstaben beginnen",
|
||||
"Name must be at most 32 characters": "Der Name darf höchstens 32 Zeichen lang sein"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "Preparing download",
|
||||
"User menu": "User menu",
|
||||
"Cleanup Warnings": "Cleanup Warnings",
|
||||
"Failed to load objects": "Failed to load objects"
|
||||
"Failed to load objects": "Failed to load objects",
|
||||
"Access Key cannot contain spaces": "Access Key cannot contain spaces",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "Name can only contain letters, numbers, underscores and hyphens, and must start with a letter",
|
||||
"Name must be at most 32 characters": "Name must be at most 32 characters"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "Preparando descarga",
|
||||
"User menu": "Menú de usuario",
|
||||
"Cleanup Warnings": "Advertencias de limpieza",
|
||||
"Failed to load objects": "No se pudieron cargar los objetos"
|
||||
"Failed to load objects": "No se pudieron cargar los objetos",
|
||||
"Access Key cannot contain spaces": "La clave de acceso no puede contener espacios",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "El nombre solo puede contener letras, números, guiones bajos y guiones, y debe comenzar con una letra",
|
||||
"Name must be at most 32 characters": "El nombre no puede tener más de 32 caracteres"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "Préparation du téléchargement",
|
||||
"User menu": "Menu utilisateur",
|
||||
"Cleanup Warnings": "Avertissements de nettoyage",
|
||||
"Failed to load objects": "Impossible de charger les objets"
|
||||
"Failed to load objects": "Impossible de charger les objets",
|
||||
"Access Key cannot contain spaces": "La clé d'accès ne peut pas contenir d'espaces",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "Le nom ne peut contenir que des lettres, des chiffres, des traits de soulignement et des traits d'union, et doit commencer par une lettre",
|
||||
"Name must be at most 32 characters": "Le nom ne doit pas dépasser 32 caractères"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "Menyiapkan unduhan",
|
||||
"User menu": "Menu pengguna",
|
||||
"Cleanup Warnings": "Peringatan pembersihan",
|
||||
"Failed to load objects": "Gagal memuat objek"
|
||||
"Failed to load objects": "Gagal memuat objek",
|
||||
"Access Key cannot contain spaces": "Kunci akses tidak boleh mengandung spasi",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "Nama hanya boleh berisi huruf, angka, garis bawah, dan tanda hubung, serta harus diawali dengan huruf",
|
||||
"Name must be at most 32 characters": "Nama tidak boleh lebih dari 32 karakter"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "Preparazione download",
|
||||
"User menu": "Menu utente",
|
||||
"Cleanup Warnings": "Avvisi di pulizia",
|
||||
"Failed to load objects": "Impossibile caricare gli oggetti"
|
||||
"Failed to load objects": "Impossibile caricare gli oggetti",
|
||||
"Access Key cannot contain spaces": "La chiave di accesso non può contenere spazi",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "Il nome può contenere solo lettere, numeri, trattini bassi e trattini, e deve iniziare con una lettera",
|
||||
"Name must be at most 32 characters": "Il nome non può superare i 32 caratteri"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "ダウンロードを準備中",
|
||||
"User menu": "ユーザーメニュー",
|
||||
"Cleanup Warnings": "クリーンアップ警告",
|
||||
"Failed to load objects": "オブジェクトの読み込みに失敗しました"
|
||||
"Failed to load objects": "オブジェクトの読み込みに失敗しました",
|
||||
"Access Key cannot contain spaces": "アクセスキーにスペースを含めることはできません",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "名前には英字、数字、アンダースコア、ハイフンのみ使用でき、英字で始まる必要があります",
|
||||
"Name must be at most 32 characters": "名前は最大32文字です"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "다운로드 준비 중",
|
||||
"User menu": "사용자 메뉴",
|
||||
"Cleanup Warnings": "정리 경고",
|
||||
"Failed to load objects": "객체를 불러오지 못했습니다"
|
||||
"Failed to load objects": "객체를 불러오지 못했습니다",
|
||||
"Access Key cannot contain spaces": "액세스 키에는 공백을 포함할 수 없습니다",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "이름은 영문자, 숫자, 밑줄, 하이픈만 사용할 수 있으며 영문자로 시작해야 합니다",
|
||||
"Name must be at most 32 characters": "이름은 최대 32자입니다"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "Preparando download",
|
||||
"User menu": "Menu do usuário",
|
||||
"Cleanup Warnings": "Avisos de limpeza",
|
||||
"Failed to load objects": "Falha ao carregar objetos"
|
||||
"Failed to load objects": "Falha ao carregar objetos",
|
||||
"Access Key cannot contain spaces": "A chave de acesso não pode conter espaços",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "O nome só pode conter letras, números, sublinhados e hifens, e deve começar com uma letra",
|
||||
"Name must be at most 32 characters": "O nome não pode ter mais de 32 caracteres"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "Подготовка загрузки",
|
||||
"User menu": "Меню пользователя",
|
||||
"Cleanup Warnings": "Предупреждения очистки",
|
||||
"Failed to load objects": "Не удалось загрузить объекты"
|
||||
"Failed to load objects": "Не удалось загрузить объекты",
|
||||
"Access Key cannot contain spaces": "Ключ доступа не может содержать пробелы",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "Имя может содержать только буквы, цифры, символы подчёркивания и дефисы и должно начинаться с буквы",
|
||||
"Name must be at most 32 characters": "Имя не должно превышать 32 символа"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "İndirme hazırlanıyor",
|
||||
"User menu": "Kullanıcı menüsü",
|
||||
"Cleanup Warnings": "Temizleme uyarıları",
|
||||
"Failed to load objects": "Nesneler yüklenemedi"
|
||||
"Failed to load objects": "Nesneler yüklenemedi",
|
||||
"Access Key cannot contain spaces": "Erişim anahtarı boşluk içeremez",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "Ad yalnızca harf, rakam, alt çizgi ve tire içerebilir ve bir harfle başlamalıdır",
|
||||
"Name must be at most 32 characters": "Ad en fazla 32 karakter olmalıdır"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "Đang chuẩn bị tải xuống",
|
||||
"User menu": "Menu người dùng",
|
||||
"Cleanup Warnings": "Cảnh báo dọn dẹp",
|
||||
"Failed to load objects": "Không thể tải đối tượng"
|
||||
"Failed to load objects": "Không thể tải đối tượng",
|
||||
"Access Key cannot contain spaces": "Khóa truy cập không được chứa khoảng trắng",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "Tên chỉ được chứa chữ cái, số, dấu gạch dưới và dấu gạch nối, và phải bắt đầu bằng một chữ cái",
|
||||
"Name must be at most 32 characters": "Tên không được dài quá 32 ký tự"
|
||||
}
|
||||
|
||||
@@ -1335,5 +1335,8 @@
|
||||
"Preparing download": "正在准备下载",
|
||||
"User menu": "用户菜单",
|
||||
"Cleanup Warnings": "清理警告",
|
||||
"Failed to load objects": "加载对象失败"
|
||||
"Failed to load objects": "加载对象失败",
|
||||
"Access Key cannot contain spaces": "访问密钥不能包含空格",
|
||||
"Name can only contain letters, numbers, underscores and hyphens, and must start with a letter": "名称只能包含字母、数字、下划线和连字符,并且必须以字母开头",
|
||||
"Name must be at most 32 characters": "名称最多 32 个字符"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user