From f5b973e15cfb330022fbafc1e23c186ca3a730e0 Mon Sep 17 00:00:00 2001 From: Jeremy Letto Date: Wed, 2 Mar 2022 22:34:57 -0600 Subject: [PATCH] Webatrice: i18n login screen (#4584) * i18n: login container and form * i18n: activate, host, and register forms * i18n: reset password forms * i18n: login dialogs, ICU formatting * i18n: login containers and components Co-authored-by: Jeremy Letto --- webclient/package-lock.json | 115 ++++++++++++++++++ webclient/package.json | 4 +- webclient/src/common.i18n.json | 23 +++- .../KnownHosts/KnownHosts.i18n.json | 7 ++ .../src/components/KnownHosts/KnownHosts.tsx | 12 +- .../Initialize/Initialize.i18n.json | 6 + .../src/containers/Initialize/Initialize.tsx | 10 +- .../src/containers/Login/Login.i18n.json | 20 ++- webclient/src/containers/Login/Login.tsx | 25 ++-- .../Unsupported/Unsupported.i18n.json | 7 ++ .../containers/Unsupported/Unsupported.tsx | 9 +- .../AccountActivationDialog.i18n.json | 7 ++ .../AccountActivationDialog.tsx | 9 +- .../KnownHostDialog/KnownHostDialog.i18n.json | 6 + .../KnownHostDialog/KnownHostDialog.tsx | 8 +- .../RegistrationDialog.i18n.json | 5 + .../RegistrationDialog/RegistrationDialog.tsx | 5 +- .../RequestPasswordResetDialog.i18n.json | 5 + .../RequestPasswordResetDialog.tsx | 5 +- .../ResetPasswordDialog.i18n.json | 5 + .../ResetPasswordDialog.tsx | 5 +- .../AccountActivationForm.i18n.json | 10 ++ .../AccountActivationForm.tsx | 10 +- .../KnownHostForm/KnownHostForm.i18n.json | 9 ++ .../src/forms/KnownHostForm/KnownHostForm.tsx | 20 +-- .../src/forms/LoginForm/LoginForm.i18n.json | 11 ++ webclient/src/forms/LoginForm/LoginForm.tsx | 25 ++-- .../forms/RegisterForm/RegisterForm.i18n.json | 10 ++ .../src/forms/RegisterForm/RegisterForm.tsx | 40 +++--- .../RequestPasswordResetForm.i18n.json | 8 ++ .../RequestPasswordResetForm.tsx | 20 +-- .../ResetPasswordForm.i18n.json | 8 ++ .../ResetPasswordForm/ResetPasswordForm.tsx | 48 +++++--- webclient/src/i18n-default.json | 2 +- webclient/src/i18n.ts | 4 +- 35 files changed, 424 insertions(+), 99 deletions(-) create mode 100644 webclient/src/components/KnownHosts/KnownHosts.i18n.json create mode 100644 webclient/src/containers/Initialize/Initialize.i18n.json create mode 100644 webclient/src/containers/Unsupported/Unsupported.i18n.json create mode 100644 webclient/src/dialogs/AccountActivationDialog/AccountActivationDialog.i18n.json create mode 100644 webclient/src/dialogs/KnownHostDialog/KnownHostDialog.i18n.json create mode 100644 webclient/src/dialogs/RegistrationDialog/RegistrationDialog.i18n.json create mode 100644 webclient/src/dialogs/RequestPasswordResetDialog/RequestPasswordResetDialog.i18n.json create mode 100644 webclient/src/dialogs/ResetPasswordDialog/ResetPasswordDialog.i18n.json create mode 100644 webclient/src/forms/AccountActivationForm/AccountActivationForm.i18n.json create mode 100644 webclient/src/forms/KnownHostForm/KnownHostForm.i18n.json create mode 100644 webclient/src/forms/LoginForm/LoginForm.i18n.json create mode 100644 webclient/src/forms/RegisterForm/RegisterForm.i18n.json create mode 100644 webclient/src/forms/RequestPasswordResetForm/RequestPasswordResetForm.i18n.json create mode 100644 webclient/src/forms/ResetPasswordForm/ResetPasswordForm.i18n.json diff --git a/webclient/package-lock.json b/webclient/package-lock.json index 7d7cc621..e5e67a92 100644 --- a/webclient/package-lock.json +++ b/webclient/package-lock.json @@ -1248,6 +1248,95 @@ } } }, + "@formatjs/ecma402-abstract": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.3.tgz", + "integrity": "sha512-kP/Buv5vVFMAYLHNvvUzr0lwRTU0u2WTy44Tqwku1X3C3lJ5dKqDCYVqA8wL+Y19Bq+MwHgxqd5FZJRCIsLRyQ==", + "dev": true, + "requires": { + "@formatjs/intl-localematcher": "0.2.24", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, + "@formatjs/fast-memoize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz", + "integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, + "@formatjs/icu-messageformat-parser": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.0.18.tgz", + "integrity": "sha512-vquIzsAJJmZ5jWVH8dEgUKcbG4yu3KqtyPet+q35SW5reLOvblkfeCXTRW2TpIwNXzdVqsJBwjbTiRiSU9JxwQ==", + "dev": true, + "requires": { + "@formatjs/ecma402-abstract": "1.11.3", + "@formatjs/icu-skeleton-parser": "1.3.5", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, + "@formatjs/icu-skeleton-parser": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.5.tgz", + "integrity": "sha512-Nhyo2/6kG7ZfgeEfo02sxviOuBcvtzH6SYUharj3DLCDJH3A/4OxkKcmx/2PWGX4bc6iSieh+FA94CsKDxnZBQ==", + "dev": true, + "requires": { + "@formatjs/ecma402-abstract": "1.11.3", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, + "@formatjs/intl-localematcher": { + "version": "0.2.24", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.24.tgz", + "integrity": "sha512-K/HRGo6EMnCbhpth/y3u4rW4aXkmQNqRe1L2G+Y5jNr3v0gYhvaucV8WixNju/INAMbPBlbsRBRo/nfjnoOnxQ==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, "@gar/promisify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", @@ -8217,6 +8306,12 @@ "@babel/runtime": "^7.14.6" } }, + "i18next-icu": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/i18next-icu/-/i18next-icu-2.0.3.tgz", + "integrity": "sha512-sZ0VCWDnHysUYQL8j/0rVOxv6rLR+SBoaqQQ2UVNfLyJCuf/bAjYPkoUQgyuDkWFo1xZjeCf4G6GBNr7gD61bQ==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -8370,6 +8465,26 @@ "side-channel": "^1.0.4" } }, + "intl-messageformat": { + "version": "9.11.4", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.11.4.tgz", + "integrity": "sha512-77TSkNubIy/hsapz6LQpyR6OADcxhWdhSaboPb5flMaALCVkPvAIxr48AlPqaMl4r1anNcvR9rpLWVdwUY1IKg==", + "dev": true, + "requires": { + "@formatjs/ecma402-abstract": "1.11.3", + "@formatjs/fast-memoize": "1.2.1", + "@formatjs/icu-messageformat-parser": "2.0.18", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", diff --git a/webclient/package.json b/webclient/package.json index 8c077478..504de4b4 100644 --- a/webclient/package.json +++ b/webclient/package.json @@ -86,6 +86,8 @@ "@typescript-eslint/parser": "^5.3.1", "eslint": "^7.32.0", "fs-extra": "^10.0.0", - "identity-obj-proxy": "^3.0.0" + "i18next-icu": "^2.0.3", + "identity-obj-proxy": "^3.0.0", + "intl-messageformat": "^9.11.4" } } diff --git a/webclient/src/common.i18n.json b/webclient/src/common.i18n.json index 019ea3cd..03225798 100644 --- a/webclient/src/common.i18n.json +++ b/webclient/src/common.i18n.json @@ -1,6 +1,27 @@ { "Common": { "language": "Translate into English.", - "disconnect": "Disconnect" + "disconnect": "Disconnect", + "label": { + "confirmPassword": "Confirm Password", + "confirmSure": "Are you sure?", + "country": "Country", + "delete": "Delete", + "email": "Email", + "hostName": "Host Name", + "hostAddress": "Host Address", + "password": "Password", + "passwordAgain": "Password Again", + "port": "Port", + "realName": "Real Name", + "saveChanges": "Save Changes", + "token": "Token", + "username": "Username" + }, + "validation": { + "minChars": "Minimum of {count} {count, plural, one {character} other {characters}} required", + "passwordsMustMatch": "Passwords don't match", + "required": "Required" + } } } diff --git a/webclient/src/components/KnownHosts/KnownHosts.i18n.json b/webclient/src/components/KnownHosts/KnownHosts.i18n.json new file mode 100644 index 00000000..3de8fd88 --- /dev/null +++ b/webclient/src/components/KnownHosts/KnownHosts.i18n.json @@ -0,0 +1,7 @@ +{ + "KnownHosts": { + "label": "Host", + "add": "Add new host", + "toast": "Host successfully {mode, select, created {created} deleted {deleted} other {edited}}." + } +} diff --git a/webclient/src/components/KnownHosts/KnownHosts.tsx b/webclient/src/components/KnownHosts/KnownHosts.tsx index 4564900e..3596f6b9 100644 --- a/webclient/src/components/KnownHosts/KnownHosts.tsx +++ b/webclient/src/components/KnownHosts/KnownHosts.tsx @@ -1,4 +1,5 @@ import { useCallback, useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { Select, MenuItem } from '@material-ui/core'; import Button from '@material-ui/core/Button'; import FormControl from '@material-ui/core/FormControl'; @@ -33,6 +34,7 @@ const KnownHosts = (props) => { const { input: { onChange }, meta, disabled } = props; const { touched, error, warning } = meta; const classes = useStyles(); + const { t } = useTranslation(); const [hostsState, setHostsState] = useState({ hosts: [], @@ -168,7 +170,7 @@ const KnownHosts = (props) => { ) } - Host + { t('KnownHosts.label') }