Could not load the accounts.
;
+ return
{user.name || user.username || user.email}
- {user.isOwner && }
+ {user.isOwner && (
+
+ )}
{user.email}
@@ -212,11 +215,13 @@ export const UsersSection = () => {
size="icon"
className={`shrink-0 ${user.osUser ? 'text-muted-foreground' : 'text-amber-500'}`}
disabled={busy}
- aria-label={user.osUser ? `Repair ${user.email}'s Linux account` : `Create a Linux account`}
+ aria-label={
+ user.osUser ? t('settings.users.repairFor', { email: user.email }) : t('settings.users.createLinux')
+ }
title={
user.osUser
- ? `Linux account: ${user.osUser} — click to repair or replace their SSH key`
- : 'No Linux account — click to create one'
+ ? t('settings.users.linuxAccountFor', { osUser: user.osUser })
+ : t('settings.users.noLinux')
}
onClick={() => void provisionLinux(user)}
>
@@ -231,11 +236,11 @@ export const UsersSection = () => {
variant="ghost"
size="icon"
className="shrink-0 text-muted-foreground"
- aria-label={`Copy ${user.email}'s SSH public key`}
- title="Copy their SSH public key (add it to their Gitea account)"
+ aria-label={t('settings.users.copySshFor', { email: user.email })}
+ title={t('settings.users.copySshTitle')}
onClick={() => {
void copyToClipboard(user.osSshPublicKey!);
- toast.success('Public key copied');
+ toast.success(t('settings.users.publicKeyCopied'));
}}
>
@@ -250,8 +255,8 @@ export const UsersSection = () => {
size="icon"
className="shrink-0 text-muted-foreground"
disabled={busy}
- aria-label={`Reset ${user.email}'s password`}
- title="Generate a new password — shown once, and signs them out everywhere"
+ aria-label={t('settings.users.resetPasswordFor', { email: user.email })}
+ title={t('settings.users.resetPasswordTitle')}
onClick={() => setConfirmReset(user)}
>
{busy ?
:
}
@@ -264,7 +269,7 @@ export const UsersSection = () => {
className="shrink-0 text-muted-foreground hover:text-destructive"
disabled={user.isOwner || busy}
onClick={() => setConfirmDelete(user)}
- aria-label={`Remove ${user.email}`}
+ aria-label={t('settings.users.removeFor', { email: user.email })}
>
{busy ?
:
}
@@ -282,19 +287,18 @@ export const UsersSection = () => {
!open && setConfirmDelete(null)}>
- Remove {confirmDelete?.email}?
-
- This deletes the account and everything belonging to it — passkeys, dashboards, saved layouts, and
- anything an installed plugin keeps for them. It cannot be undone.
-
+
+ {t('settings.users.removeTitle', { email: confirmDelete?.email ?? '' })}
+
+ {t('settings.users.removeBody')}
- Cancel
+ {tUi('button.cancel')}
confirmDelete && void remove(confirmDelete)}
>
- Remove account
+ {t('settings.users.removeAccount')}
@@ -305,23 +309,16 @@ export const UsersSection = () => {
!open && setConfirmReset(null)}>
- Reset the password for {confirmReset?.email}?
+ {t('settings.users.resetTitle', { email: confirmReset?.email ?? '' })}
- A new password is generated and shown to you once — it is not stored anywhere and cannot be looked up
- afterwards. Their existing password stops working immediately, and they are signed out everywhere.
- {confirmReset?.osUser ? (
- <>
- {' '}
- Their Linux account ({confirmReset.osUser}) is not affected: it has no password, and SSH keys are
- unchanged.
- >
- ) : null}
+ {t('settings.users.resetBody')}
+ {confirmReset?.osUser ? ` ${t('settings.users.resetLinuxNote', { osUser: confirmReset.osUser })}` : null}
- Cancel
+ {tUi('button.cancel')}
confirmReset && void resetPassword(confirmReset)}>
- Generate a new password
+ {t('settings.users.generateNewPassword')}
@@ -345,11 +342,11 @@ export const UsersSection = () => {
variant="ghost"
size="icon"
className="shrink-0"
- aria-label="Copy the new password"
+ aria-label={t('settings.users.copyNewPassword')}
onClick={() => {
if (!newPassword) return;
void copyToClipboard(newPassword.password).then((ok) =>
- ok ? toast.success('Password copied') : toast.error('Could not copy — select it and copy by hand'),
+ ok ? toast.success(t('settings.users.passwordCopied')) : toast.error(t('settings.users.copyFailed')),
);
}}
>
@@ -358,7 +355,7 @@ export const UsersSection = () => {
- setNewPassword(null)}>Done
+ setNewPassword(null)}>{t('settings.users.done')}
diff --git a/src/apps/officer-web/locales/en-GB.json b/src/apps/officer-web/locales/en-GB.json
index 3c40d736..dde73743 100644
--- a/src/apps/officer-web/locales/en-GB.json
+++ b/src/apps/officer-web/locales/en-GB.json
@@ -309,6 +309,57 @@
"saveFailed": "Failed to save provider",
"connectedTo": "Connected to {{name}}"
}
+ },
+ "users": {
+ "loadingPermissions": "Loading permissions…",
+ "permissionsFailed": "Could not load permissions.",
+ "deniedUnlessGranted": "Everything is denied unless granted here.",
+ "read": "Read",
+ "full": "Full",
+ "noAccess": "No access",
+ "role": "Role",
+ "permissionsSaved": "Saved what {{role}}s can reach",
+ "copyBeforeClosing": "Copy what you need before closing — none of it can be shown again.",
+ "password": "Password",
+ "linuxAccount": "Linux account",
+ "sshKey": "Their SSH public key",
+ "addToGitea": "Add this to their Gitea account",
+ "linuxIncomplete": "The account works, but its Linux side did not finish",
+ "done": "Done",
+ "addAccount": "Add account",
+ "newAccount": "New account",
+ "email": "Email",
+ "name": "Name",
+ "username": "Username",
+ "usernameHint": "Letters, numbers, dots, hyphens and underscores.",
+ "generatePassword": "Generate a password",
+ "copyPassword": "Copy the password",
+ "passwordHint": "At least 12 characters, with upper and lower case, a number and a symbol.",
+ "sshPlaceholder": "ssh-ed25519 AAAAC3Nza… ana@laptop",
+ "passwordCopied": "Password copied",
+ "loadingAccounts": "Loading accounts…",
+ "accountsFailed": "Could not load the accounts.",
+ "removeAccount": "Remove account",
+ "generateNewPassword": "Generate a new password",
+ "serverOwner": "Server owner",
+ "copySshTitle": "Copy their SSH public key (add it to their Gitea account)",
+ "resetPasswordTitle": "Generate a new password — shown once, and signs them out everywhere",
+ "copyNewPassword": "Copy the new password",
+ "publicKeyCopied": "Public key copied",
+ "copyFailed": "Could not copy — select it and copy by hand",
+ "repairFor": "Repair {{email}}’s Linux account",
+ "linuxAccountFor": "Linux account: {{osUser}} — click to repair or replace their SSH key",
+ "copySshFor": "Copy {{email}}’s SSH public key",
+ "resetPasswordFor": "Reset {{email}}’s password",
+ "removeFor": "Remove {{email}}",
+ "provisionPrompt": "Linux account for {{email}}.\n\nPaste an SSH public key to allow them to SSH in, or leave empty to keep the current one.",
+ "createLinux": "Create a Linux account",
+ "noLinux": "No Linux account — click to create one",
+ "removeTitle": "Remove {{email}}?",
+ "removeBody": "This deletes the account and everything belonging to it — passkeys, dashboards, saved layouts, and anything an installed plugin keeps for them. It cannot be undone.",
+ "resetTitle": "Reset the password for {{email}}?",
+ "resetBody": "A new password is generated and shown to you once — it is not stored anywhere and cannot be looked up afterwards. Their existing password stops working immediately, and they are signed out everywhere.",
+ "resetLinuxNote": "Their Linux account ({{osUser}}) is not affected: it has no password, and SSH keys are unchanged."
}
},
"header": {
diff --git a/src/apps/officer-web/locales/pt-PT.json b/src/apps/officer-web/locales/pt-PT.json
index dacbad94..ca40b7e7 100644
--- a/src/apps/officer-web/locales/pt-PT.json
+++ b/src/apps/officer-web/locales/pt-PT.json
@@ -309,6 +309,57 @@
"saveFailed": "Falha ao guardar o fornecedor",
"connectedTo": "Ligado a {{name}}"
}
+ },
+ "users": {
+ "loadingPermissions": "A carregar permissões…",
+ "permissionsFailed": "Não foi possível carregar as permissões.",
+ "deniedUnlessGranted": "Tudo é negado a menos que seja concedido aqui.",
+ "read": "Leitura",
+ "full": "Total",
+ "noAccess": "Sem acesso",
+ "role": "Função",
+ "permissionsSaved": "Guardado o que os {{role}} podem alcançar",
+ "copyBeforeClosing": "Copie o que precisa antes de fechar — nada disto pode ser mostrado outra vez.",
+ "password": "Palavra-passe",
+ "linuxAccount": "Conta Linux",
+ "sshKey": "A sua chave pública SSH",
+ "addToGitea": "Adicione isto à conta Gitea dele",
+ "linuxIncomplete": "A conta funciona, mas a parte Linux não ficou concluída",
+ "done": "Concluído",
+ "addAccount": "Adicionar conta",
+ "newAccount": "Nova conta",
+ "email": "Email",
+ "name": "Nome",
+ "username": "Nome de utilizador",
+ "usernameHint": "Letras, números, pontos, hífenes e underscores.",
+ "generatePassword": "Gerar uma palavra-passe",
+ "copyPassword": "Copiar a palavra-passe",
+ "passwordHint": "Pelo menos 12 caracteres, com maiúsculas e minúsculas, um número e um símbolo.",
+ "sshPlaceholder": "ssh-ed25519 AAAAC3Nza… ana@portatil",
+ "passwordCopied": "Palavra-passe copiada",
+ "loadingAccounts": "A carregar contas…",
+ "accountsFailed": "Não foi possível carregar as contas.",
+ "removeAccount": "Remover conta",
+ "generateNewPassword": "Gerar uma nova palavra-passe",
+ "serverOwner": "Proprietário do servidor",
+ "copySshTitle": "Copiar a sua chave pública SSH (adicione-a à conta Gitea dele)",
+ "resetPasswordTitle": "Gerar uma nova palavra-passe — mostrada uma única vez, e termina a sessão em todo o lado",
+ "copyNewPassword": "Copiar a nova palavra-passe",
+ "publicKeyCopied": "Chave pública copiada",
+ "copyFailed": "Não foi possível copiar — selecione e copie manualmente",
+ "repairFor": "Reparar a conta Linux de {{email}}",
+ "linuxAccountFor": "Conta Linux: {{osUser}} — clique para reparar ou substituir a chave SSH",
+ "copySshFor": "Copiar a chave pública SSH de {{email}}",
+ "resetPasswordFor": "Redefinir a palavra-passe de {{email}}",
+ "removeFor": "Remover {{email}}",
+ "provisionPrompt": "Conta Linux para {{email}}.\n\nCole uma chave pública SSH para lhe permitir aceder por SSH, ou deixe vazio para manter a atual.",
+ "createLinux": "Criar uma conta Linux",
+ "noLinux": "Sem conta Linux — clique para criar uma",
+ "removeTitle": "Remover {{email}}?",
+ "removeBody": "Isto elimina a conta e tudo o que lhe pertence — passkeys, painéis, layouts guardados e tudo o que qualquer plugin instalado guarde para ela. Não pode ser desfeito.",
+ "resetTitle": "Redefinir a palavra-passe de {{email}}?",
+ "resetBody": "É gerada uma nova palavra-passe e mostrada uma única vez — não é guardada em nenhum lugar e não pode ser consultada depois. A palavra-passe atual deixa de funcionar imediatamente, e a sessão é terminada em todo o lado.",
+ "resetLinuxNote": "A conta Linux ({{osUser}}) não é afetada: não tem palavra-passe, e as chaves SSH ficam inalteradas."
}
},
"header": {