Spanish Translation Account form and New Password (#1547)
* Translations From ReduxFormUtils * Translations for Account, AiKey and New Password * NewPasswordForm
This commit is contained in:
parent
ff40de36ca
commit
236cdac7ed
8 changed files with 187 additions and 66 deletions
|
@ -1,6 +1,5 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import Button from '../../../common/Button';
|
||||
import { PlusIcon } from '../../../common/icons';
|
||||
import CopyableInput from '../../IDE/components/CopyableInput';
|
||||
|
@ -12,7 +11,7 @@ export const APIKeyPropType = PropTypes.shape({
|
|||
token: PropTypes.object,
|
||||
label: PropTypes.string.isRequired,
|
||||
createdAt: PropTypes.string.isRequired,
|
||||
lastUsedAt: PropTypes.string,
|
||||
lastUsedAt: PropTypes.string
|
||||
});
|
||||
|
||||
class APIKeyForm extends React.Component {
|
||||
|
@ -39,7 +38,7 @@ class APIKeyForm extends React.Component {
|
|||
}
|
||||
|
||||
removeKey(key) {
|
||||
const message = `Are you sure you want to delete "${key.label}"?`;
|
||||
const message = this.props.t('APIKeyForm.ConfirmDelete', { key_label: key.label });
|
||||
|
||||
if (window.confirm(message)) {
|
||||
this.props.removeApiKey(key.id);
|
||||
|
@ -51,10 +50,10 @@ class APIKeyForm extends React.Component {
|
|||
|
||||
if (hasApiKeys) {
|
||||
return (
|
||||
<APIKeyList apiKeys={this.props.apiKeys} onRemove={this.removeKey} />
|
||||
<APIKeyList apiKeys={this.props.apiKeys} onRemove={this.removeKey} t={this.props.t} />
|
||||
);
|
||||
}
|
||||
return <p>You have no exsiting tokens.</p>;
|
||||
return <p>{this.props.t('APIKeyForm.NoTokens')}</p>;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -63,20 +62,18 @@ class APIKeyForm extends React.Component {
|
|||
return (
|
||||
<div className="api-key-form">
|
||||
<p className="api-key-form__summary">
|
||||
Personal Access Tokens act like your password to allow automated
|
||||
scripts to access the Editor API. Create a token for each script
|
||||
that needs access.
|
||||
{this.props.t('APIKeyForm.Summary')}
|
||||
</p>
|
||||
|
||||
<div className="api-key-form__section">
|
||||
<h3 className="api-key-form__title">Create new token</h3>
|
||||
<h3 className="api-key-form__title">{this.props.t('APIKeyForm.CreateToken')}</h3>
|
||||
<form className="form form--inline" onSubmit={this.addKey}>
|
||||
<label htmlFor="keyLabel" className="form__label form__label--hidden ">What is this token for?</label>
|
||||
<label htmlFor="keyLabel" className="form__label form__label--hidden ">{this.props.t('APIKeyForm.TokenLabel')}</label>
|
||||
<input
|
||||
className="form__input"
|
||||
id="keyLabel"
|
||||
onChange={(event) => { this.setState({ keyLabel: event.target.value }); }}
|
||||
placeholder="What is this token for? e.g. Example import script"
|
||||
placeholder={this.props.t('APIKeyForm.TokenPlaceholder')}
|
||||
type="text"
|
||||
value={this.state.keyLabel}
|
||||
/>
|
||||
|
@ -86,17 +83,16 @@ class APIKeyForm extends React.Component {
|
|||
label="Create new key"
|
||||
type="submit"
|
||||
>
|
||||
Create
|
||||
{this.props.t('APIKeyForm.CreateTokenSubmit')}
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
{
|
||||
keyWithToken && (
|
||||
<div className="api-key-form__new-token">
|
||||
<h4 className="api-key-form__new-token__title">Your new access token</h4>
|
||||
<h4 className="api-key-form__new-token__title">{this.props.t('APIKeyForm.NewTokenTitle')}</h4>
|
||||
<p className="api-key-form__new-token__info">
|
||||
Make sure to copy your new personal access token now.
|
||||
You won’t be able to see it again!
|
||||
{this.props.t('APIKeyForm.NewTokenInfo')}
|
||||
</p>
|
||||
<CopyableInput label={keyWithToken.label} value={keyWithToken.token} />
|
||||
</div>
|
||||
|
@ -105,7 +101,7 @@ class APIKeyForm extends React.Component {
|
|||
</div>
|
||||
|
||||
<div className="api-key-form__section">
|
||||
<h3 className="api-key-form__title">Existing tokens</h3>
|
||||
<h3 className="api-key-form__title">{this.props.t('APIKeyForm.ExistingTokensTitle')}</h3>
|
||||
{this.renderApiKeys()}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -117,6 +113,7 @@ APIKeyForm.propTypes = {
|
|||
apiKeys: PropTypes.arrayOf(PropTypes.shape(APIKeyPropType)).isRequired,
|
||||
createApiKey: PropTypes.func.isRequired,
|
||||
removeApiKey: PropTypes.func.isRequired,
|
||||
t: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default APIKeyForm;
|
||||
|
|
|
@ -8,22 +8,22 @@ import { APIKeyPropType } from './APIKeyForm';
|
|||
|
||||
import TrashCanIcon from '../../../images/trash-can.svg';
|
||||
|
||||
function APIKeyList({ apiKeys, onRemove }) {
|
||||
function APIKeyList({ apiKeys, onRemove, t }) {
|
||||
return (
|
||||
<table className="api-key-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Created on</th>
|
||||
<th>Last used</th>
|
||||
<th>Actions</th>
|
||||
<th>{t('APIKeyList.Name')}</th>
|
||||
<th>{t('APIKeyList.Created')}</th>
|
||||
<th>{t('APIKeyList.LastUsed')}</th>
|
||||
<th>{t('APIKeyList.Actions')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{orderBy(apiKeys, ['createdAt'], ['desc']).map((key) => {
|
||||
const lastUsed = key.lastUsedAt ?
|
||||
distanceInWordsToNow(new Date(key.lastUsedAt), { addSuffix: true }) :
|
||||
'Never';
|
||||
t('APIKeyList.Never');
|
||||
|
||||
return (
|
||||
<tr key={key.id}>
|
||||
|
@ -34,7 +34,7 @@ function APIKeyList({ apiKeys, onRemove }) {
|
|||
<button
|
||||
className="api-key-list__delete-button"
|
||||
onClick={() => onRemove(key)}
|
||||
aria-label="Delete API Key"
|
||||
aria-label={t('APIKeyList.DeleteARIA')}
|
||||
>
|
||||
<TrashCanIcon focusable="false" aria-hidden="true" />
|
||||
</button>
|
||||
|
@ -50,6 +50,7 @@ function APIKeyList({ apiKeys, onRemove }) {
|
|||
APIKeyList.propTypes = {
|
||||
apiKeys: PropTypes.arrayOf(PropTypes.shape(APIKeyPropType)).isRequired,
|
||||
onRemove: PropTypes.func.isRequired,
|
||||
t: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default APIKeyList;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
||||
import Button from '../../../common/Button';
|
||||
|
||||
|
@ -13,7 +14,8 @@ function AccountForm(props) {
|
|||
initiateVerification,
|
||||
submitting,
|
||||
invalid,
|
||||
pristine
|
||||
pristine,
|
||||
t
|
||||
} = props;
|
||||
|
||||
const handleInitiateVerification = (evt) => {
|
||||
|
@ -24,10 +26,10 @@ function AccountForm(props) {
|
|||
return (
|
||||
<form className="form" onSubmit={handleSubmit(props.updateSettings)}>
|
||||
<p className="form__field">
|
||||
<label htmlFor="email" className="form__label">Email</label>
|
||||
<label htmlFor="email" className="form__label">{t('AccountForm.Email')}</label>
|
||||
<input
|
||||
className="form__input"
|
||||
aria-label="email"
|
||||
aria-label={t('AccountForm.EmailARIA')}
|
||||
type="text"
|
||||
id="email"
|
||||
{...domOnlyProps(email)}
|
||||
|
@ -38,16 +40,16 @@ function AccountForm(props) {
|
|||
user.verified !== 'verified' &&
|
||||
(
|
||||
<p className="form__context">
|
||||
<span className="form__status">Unconfirmed.</span>
|
||||
<span className="form__status">{t('AccountForm.Unconfirmed')}</span>
|
||||
{
|
||||
user.emailVerificationInitiate === true ?
|
||||
(
|
||||
<span className="form__status"> Confirmation sent, check your email.</span>
|
||||
<span className="form__status"> {t('AccountForm.EmailSent')}</span>
|
||||
) :
|
||||
(
|
||||
<Button
|
||||
onClick={handleInitiateVerification}
|
||||
>Resend confirmation email
|
||||
>{t('AccountForm.Resend')}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
@ -55,10 +57,10 @@ function AccountForm(props) {
|
|||
)
|
||||
}
|
||||
<p className="form__field">
|
||||
<label htmlFor="username" className="form__label">User Name</label>
|
||||
<label htmlFor="username" className="form__label">{t('AccountForm.UserName')}</label>
|
||||
<input
|
||||
className="form__input"
|
||||
aria-label="username"
|
||||
aria-label={t('AccountForm.UserNameARIA')}
|
||||
type="text"
|
||||
id="username"
|
||||
defaultValue={username}
|
||||
|
@ -67,10 +69,10 @@ function AccountForm(props) {
|
|||
{username.touched && username.error && <span className="form-error">{username.error}</span>}
|
||||
</p>
|
||||
<p className="form__field">
|
||||
<label htmlFor="current password" className="form__label">Current Password</label>
|
||||
<label htmlFor="current password" className="form__label">{t('AccountForm.CurrentPassword')}</label>
|
||||
<input
|
||||
className="form__input"
|
||||
aria-label="currentPassword"
|
||||
aria-label={t('AccountForm.CurrentPasswordARIA')}
|
||||
type="password"
|
||||
id="currentPassword"
|
||||
{...domOnlyProps(currentPassword)}
|
||||
|
@ -82,10 +84,10 @@ function AccountForm(props) {
|
|||
}
|
||||
</p>
|
||||
<p className="form__field">
|
||||
<label htmlFor="new password" className="form__label">New Password</label>
|
||||
<label htmlFor="new password" className="form__label">{t('AccountForm.NewPassword')}</label>
|
||||
<input
|
||||
className="form__input"
|
||||
aria-label="newPassword"
|
||||
aria-label={t('AccountForm.NewPasswordARIA')}
|
||||
type="password"
|
||||
id="newPassword"
|
||||
{...domOnlyProps(newPassword)}
|
||||
|
@ -95,7 +97,7 @@ function AccountForm(props) {
|
|||
<Button
|
||||
type="submit"
|
||||
disabled={submitting || invalid || pristine}
|
||||
>Save All Settings
|
||||
>{t('AccountForm.SubmitSaveAllSettings')}
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
|
@ -118,6 +120,7 @@ AccountForm.propTypes = {
|
|||
submitting: PropTypes.bool,
|
||||
invalid: PropTypes.bool,
|
||||
pristine: PropTypes.bool,
|
||||
t: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
AccountForm.defaultProps = {
|
||||
|
@ -126,4 +129,4 @@ AccountForm.defaultProps = {
|
|||
invalid: false
|
||||
};
|
||||
|
||||
export default AccountForm;
|
||||
export default withTranslation()(AccountForm);
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
||||
import Button from '../../../common/Button';
|
||||
|
||||
function NewPasswordForm(props) {
|
||||
const {
|
||||
fields: { password, confirmPassword }, handleSubmit, submitting, invalid, pristine
|
||||
fields: { password, confirmPassword }, handleSubmit, submitting, invalid, pristine,
|
||||
t
|
||||
} = props;
|
||||
return (
|
||||
<form className="form" onSubmit={handleSubmit(props.updatePassword.bind(this, props.params.reset_password_token))}>
|
||||
<p className="form__field">
|
||||
<label htmlFor="password" className="form__label">Password</label>
|
||||
<label htmlFor="password" className="form__label">{t('NewPasswordForm.Title')}</label>
|
||||
<input
|
||||
className="form__input"
|
||||
aria-label="password"
|
||||
aria-label={t('NewPasswordForm.TitleARIA')}
|
||||
type="password"
|
||||
id="Password"
|
||||
{...domOnlyProps(password)}
|
||||
|
@ -22,11 +23,11 @@ function NewPasswordForm(props) {
|
|||
{password.touched && password.error && <span className="form-error">{password.error}</span>}
|
||||
</p>
|
||||
<p className="form__field">
|
||||
<label htmlFor="confirm password" className="form__label">Confirm Password</label>
|
||||
<label htmlFor="confirm password" className="form__label">{t('NewPasswordForm.ConfirmPassword')}</label>
|
||||
<input
|
||||
className="form__input"
|
||||
type="password"
|
||||
aria-label="confirm password"
|
||||
aria-label={t('NewPasswordForm.ConfirmPasswordARIA')}
|
||||
id="confirm password"
|
||||
{...domOnlyProps(confirmPassword)}
|
||||
/>
|
||||
|
@ -36,7 +37,7 @@ function NewPasswordForm(props) {
|
|||
<span className="form-error">{confirmPassword.error}</span>
|
||||
}
|
||||
</p>
|
||||
<Button type="submit" disabled={submitting || invalid || pristine}>Set New Password</Button>
|
||||
<Button type="submit" disabled={submitting || invalid || pristine}>{t('NewPasswordForm.SubmitSetNewPassword')}</Button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
@ -54,6 +55,7 @@ NewPasswordForm.propTypes = {
|
|||
params: PropTypes.shape({
|
||||
reset_password_token: PropTypes.string,
|
||||
}).isRequired,
|
||||
t: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
NewPasswordForm.defaultProps = {
|
||||
|
@ -62,4 +64,4 @@ NewPasswordForm.defaultProps = {
|
|||
submitting: false
|
||||
};
|
||||
|
||||
export default NewPasswordForm;
|
||||
export default withTranslation()(NewPasswordForm);
|
||||
|
|
|
@ -4,6 +4,7 @@ import { reduxForm } from 'redux-form';
|
|||
import { bindActionCreators } from 'redux';
|
||||
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { updateSettings, initiateVerification, createApiKey, removeApiKey } from '../actions';
|
||||
import AccountForm from '../components/AccountForm';
|
||||
import apiClient from '../../../utils/apiClient';
|
||||
|
@ -16,9 +17,11 @@ function SocialLoginPanel(props) {
|
|||
return (
|
||||
<React.Fragment>
|
||||
<AccountForm {...props} />
|
||||
<h2 className="form-container__divider">Social Login</h2>
|
||||
{/* eslint-disable-next-line react/prop-types */}
|
||||
<h2 className="form-container__divider">{props.t('AccountView.SocialLogin')}</h2>
|
||||
<p className="account__social-text">
|
||||
Use your GitHub or Google account to log into the p5.js Web Editor.
|
||||
{/* eslint-disable-next-line react/prop-types */}
|
||||
{props.t('AccountView.SocialLoginDescription')}
|
||||
</p>
|
||||
<div className="account__social-stack">
|
||||
<SocialAuthButton service={SocialAuthButton.services.github} />
|
||||
|
@ -39,21 +42,21 @@ class AccountView extends React.Component {
|
|||
return (
|
||||
<div className="account-settings__container">
|
||||
<Helmet>
|
||||
<title>p5.js Web Editor | Account Settings</title>
|
||||
<title>{this.props.t('AccountView.Title')}</title>
|
||||
</Helmet>
|
||||
|
||||
<Nav layout="dashboard" />
|
||||
|
||||
<main className="account-settings">
|
||||
<header className="account-settings__header">
|
||||
<h1 className="account-settings__title">Account Settings</h1>
|
||||
<h1 className="account-settings__title">{this.props.t('AccountView.Settings')}</h1>
|
||||
</header>
|
||||
{accessTokensUIEnabled &&
|
||||
<Tabs className="account__tabs">
|
||||
<TabList>
|
||||
<div className="tabs__titles">
|
||||
<Tab><h4 className="tabs__title">Account</h4></Tab>
|
||||
{accessTokensUIEnabled && <Tab><h4 className="tabs__title">Access Tokens</h4></Tab>}
|
||||
<Tab><h4 className="tabs__title">{this.props.t('AccountView.AccountTab')}</h4></Tab>
|
||||
{accessTokensUIEnabled && <Tab><h4 className="tabs__title">{this.props.t('AccountView.AccessTokensTab')}</h4></Tab>}
|
||||
</div>
|
||||
</TabList>
|
||||
<TabPanel>
|
||||
|
@ -107,13 +110,14 @@ function asyncValidate(formProps, dispatch, props) {
|
|||
|
||||
AccountView.propTypes = {
|
||||
previousPath: PropTypes.string.isRequired,
|
||||
theme: PropTypes.string.isRequired
|
||||
theme: PropTypes.string.isRequired,
|
||||
t: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default reduxForm({
|
||||
export default withTranslation()(reduxForm({
|
||||
form: 'updateAllSettings',
|
||||
fields: ['username', 'email', 'currentPassword', 'newPassword'],
|
||||
validate: validateSettings,
|
||||
asyncValidate,
|
||||
asyncBlurFields: ['username', 'email', 'currentPassword']
|
||||
}, mapStateToProps, mapDispatchToProps)(AccountView);
|
||||
}, mapStateToProps, mapDispatchToProps)(AccountView));
|
||||
|
|
|
@ -4,6 +4,8 @@ import { reduxForm } from 'redux-form';
|
|||
import classNames from 'classnames';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import i18next from 'i18next';
|
||||
import NewPasswordForm from '../components/NewPasswordForm';
|
||||
import * as UserActions from '../actions';
|
||||
import Nav from '../../../components/Nav';
|
||||
|
@ -20,13 +22,13 @@ function NewPasswordView(props) {
|
|||
<Nav layout="dashboard" />
|
||||
<div className={newPasswordClass}>
|
||||
<Helmet>
|
||||
<title>p5.js Web Editor | New Password</title>
|
||||
<title>{props.t('NewPasswordView.Title')}</title>
|
||||
</Helmet>
|
||||
<div className="form-container__content">
|
||||
<h2 className="form-container__title">Set a New Password</h2>
|
||||
<h2 className="form-container__title">{props.t('NewPasswordView.Description')}</h2>
|
||||
<NewPasswordForm {...props} />
|
||||
<p className="new-password__invalid">
|
||||
The password reset token is invalid or has expired.
|
||||
{props.t('NewPasswordView.TokenInvalidOrExpired')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -41,21 +43,22 @@ NewPasswordView.propTypes = {
|
|||
validateResetPasswordToken: PropTypes.func.isRequired,
|
||||
user: PropTypes.shape({
|
||||
resetPasswordInvalid: PropTypes.bool
|
||||
}).isRequired
|
||||
}).isRequired,
|
||||
t: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
function validate(formProps) {
|
||||
const errors = {};
|
||||
|
||||
if (!formProps.password) {
|
||||
errors.password = 'Please enter a password';
|
||||
errors.password = i18next.t('NewPasswordView.EmptyPassword');
|
||||
}
|
||||
if (!formProps.confirmPassword) {
|
||||
errors.confirmPassword = 'Please enter a password confirmation';
|
||||
errors.confirmPassword = i18next.t('NewPasswordView.PasswordConfirmation');
|
||||
}
|
||||
|
||||
if (formProps.password !== formProps.confirmPassword) {
|
||||
errors.password = 'Passwords must match';
|
||||
errors.password = i18next.t('NewPasswordView.PasswordMismatch');
|
||||
}
|
||||
|
||||
return errors;
|
||||
|
@ -71,8 +74,8 @@ function mapDispatchToProps(dispatch) {
|
|||
return bindActionCreators(UserActions, dispatch);
|
||||
}
|
||||
|
||||
export default reduxForm({
|
||||
export default withTranslation()(reduxForm({
|
||||
form: 'new-password',
|
||||
fields: ['password', 'confirmPassword'],
|
||||
validate
|
||||
}, mapStateToProps, mapDispatchToProps)(NewPasswordView);
|
||||
}, mapStateToProps, mapDispatchToProps)(NewPasswordView));
|
||||
|
|
|
@ -232,5 +232,62 @@
|
|||
"errorEmptyUsername": "Please enter a username.",
|
||||
"errorLongUsername": "Username must be less than 20 characters.",
|
||||
"errorValidUsername": "Username must only consist of numbers, letters, periods, dashes, and underscores."
|
||||
},
|
||||
"NewPasswordView": {
|
||||
"Title": "p5.js Web Editor | New Password",
|
||||
"Description": "Set a New Password",
|
||||
"TokenInvalidOrExpired": "The password reset token is invalid or has expired.",
|
||||
"EmptyPassword": "Please enter a password",
|
||||
"PasswordConfirmation": "Please enter a password confirmation",
|
||||
"PasswordMismatch": "Passwords must match"
|
||||
},
|
||||
"AccountForm": {
|
||||
"Email": "Email",
|
||||
"EmailARIA": "email",
|
||||
"Unconfirmed": "Unconfirmed.",
|
||||
"EmailSent": "Confirmation sent, check your email.",
|
||||
"Resend": "Resend confirmation email",
|
||||
"UserName": "User Name",
|
||||
"UserNameARIA": "Username",
|
||||
"CurrentPassword": "Current Password",
|
||||
"CurrentPasswordARIA": "Current Password",
|
||||
"NewPassword": "New Password",
|
||||
"NewPasswordARIA": "New Password",
|
||||
"SubmitSaveAllSettings": "Save All Settings"
|
||||
},
|
||||
"AccountView": {
|
||||
"SocialLogin": "Social Login",
|
||||
"SocialLoginDescription": "Use your GitHub or Google account to log into the p5.js Web Editor.",
|
||||
"Title": "p5.js Web Editor | Account Settings",
|
||||
"Settings": "Account Settings",
|
||||
"AccountTab": "Account",
|
||||
"AccessTokensTab": "Access Tokens"
|
||||
},
|
||||
"APIKeyForm": {
|
||||
"ConfirmDelete": "Are you sure you want to delete {{key_label}}?",
|
||||
"Summary": "Personal Access Tokens act like your password to allow automated\n scripts to access the Editor API. Create a token for each script\n that needs access.",
|
||||
"CreateToken": "Create new token",
|
||||
"TokenLabel": "What is this token for?",
|
||||
"TokenPlaceholder": "What is this token for? e.g. Example import script",
|
||||
"CreateTokenSubmit": "Create",
|
||||
"NoTokens": "You have no existing tokens.",
|
||||
"NewTokenTitle": "Your new access token",
|
||||
"NewTokenInfo": "Make sure to copy your new personal access token now.\n You won’t be able to see it again!",
|
||||
"ExistingTokensTitle": "Existing tokens"
|
||||
},
|
||||
"APIKeyList": {
|
||||
"Name": "Name",
|
||||
"Created": "Created on",
|
||||
"LastUsed": "Last used",
|
||||
"Actions": "Actions",
|
||||
"Never": "Never",
|
||||
"DeleteARIA": "Delete API Key"
|
||||
},
|
||||
"NewPasswordForm": {
|
||||
"Title": "Password",
|
||||
"TitleARIA": "Password",
|
||||
"ConfirmPassword": "Confirm Password",
|
||||
"ConfirmPasswordARIA": "Confirm Password",
|
||||
"SubmitSetNewPassword": "Set New Password"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -232,8 +232,62 @@
|
|||
"errorEmptyUsername": "Por favor introduce tu identificación",
|
||||
"errorLongUsername": "La identificación debe ser menor a 20 caracteres.",
|
||||
"errorValidUsername": "La identificación debe consistir solamente de números, letras, puntos, guiones y guiones bajos."
|
||||
|
||||
},
|
||||
"NewPasswordView": {
|
||||
"Title": "Editor Web p5.js | Nueva Contraseña",
|
||||
"Description": "Define una nueva contraseña",
|
||||
"TokenInvalidOrExpired": "El token para regenerar la contraseña es inválido o ha expirado.",
|
||||
"EmptyPassword": "Por favor introduce una contraseña",
|
||||
"PasswordConfirmation": "Por favor confirma la contraseña",
|
||||
"PasswordMismatch": "Las contraseña deben coincidir"
|
||||
},
|
||||
"AccountForm": {
|
||||
"Email": "Correo Electrónico",
|
||||
"EmailARIA": "correo electrónico",
|
||||
"Unconfirmed": "Sin confirmar.",
|
||||
"EmailSent": "Confirmación enviada, revisa tu correo electrónico.",
|
||||
"Resend": "Reenviar correo de confirmación",
|
||||
"UserName": "Nombre de Identificación",
|
||||
"UserNameARIA": "Nombre de identificación",
|
||||
"CurrentPassword": "Contraseña Actual",
|
||||
"CurrentPasswordARIA": "Contraseña Actual",
|
||||
"NewPassword": "Nueva Contraseña",
|
||||
"NewPasswordARIA": "Nueva Contraseña",
|
||||
"SubmitSaveAllSettings": "Guardar Todas Las Configuraciones"
|
||||
},
|
||||
"AccountView": {
|
||||
"SocialLogin": "Identificacion usando redes sociales",
|
||||
"SocialLoginDescription": "Usa tu cuenta de GitHub o Google para acceder al Editor Web de p5.js .",
|
||||
"Title": "Editor Web p5.js | Configuración Cuenta",
|
||||
"Settings": "Configuración de la Cuenta",
|
||||
"AccountTab": "Cuenta",
|
||||
"AccessTokensTab": "Tokens de acceso"
|
||||
},
|
||||
"APIKeyForm": {
|
||||
"ConfirmDelete": "¿Estas seguro que quieres borrar {{key_label}}?",
|
||||
"Summary": " Los Tokens de acceso personal actuan como tu contraseña para permitir\n a scripts automáticos acceder al API del Editor. Crea un token por cada script \n que necesite acceso.",
|
||||
"CreateToken": "Crear nuevo token",
|
||||
"TokenLabel": "¿Para que es este token?",
|
||||
"TokenPlaceholder": "¿Para que es este token? p.e. Ejemplo para Importar un Archivo",
|
||||
"CreateTokenSubmit": "Crear",
|
||||
"NoTokens": "No tienes tokens.",
|
||||
"NewTokenTitle": "Tu nuevo token de acceso",
|
||||
"NewTokenInfo": "Asegurate de copiar tu token ahora mismo.\n ¡No podras verlo de nuevo!",
|
||||
"ExistingTokensTitle": "Tokens existentes"
|
||||
},
|
||||
"APIKeyList": {
|
||||
"Name": "Nombre",
|
||||
"Created": "Creado en",
|
||||
"LastUsed": "Usado por última vez",
|
||||
"Actions": "Acciones",
|
||||
"Never": "Nunca",
|
||||
"DeleteARIA": "Borrar clave de API"
|
||||
},
|
||||
"NewPasswordForm": {
|
||||
"Title": "Contraseña",
|
||||
"TitleARIA": "Contraseña",
|
||||
"ConfirmPassword": "Confirmar Contraseña",
|
||||
"ConfirmPasswordARIA": "Confirmar contraseña",
|
||||
"SubmitSetNewPassword": "Crear Nueva Contraseña"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue