UI : Localization fix (#10183)

* Localization fix

* fix unit test issue

* changes as per comments

---------

Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
Co-authored-by: Sachin Chaurasiya <sachinchaurasiyachotey87@gmail.com>
This commit is contained in:
Ashish Gupta 2023-02-17 10:17:12 +04:00 committed by GitHub
parent 5b94f5ae70
commit 2ba6211b58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 142 additions and 61 deletions

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none"><path fill="#7147E8" stroke="#7147E8" stroke-width=".2" d="M11.278 2.166H9.955v-.592c0-.191-.21-.278-.4-.278H8.526C8.283.599 7.674.25 6.977.25a1.584 1.584 0 0 0-1.549 1.045h-1.01c-.19 0-.382.087-.382.278v.592H2.712a1.48 1.48 0 0 0-1.462 1.41v8.85c0 .767.696 1.324 1.462 1.324h8.566c.766 0 1.462-.557 1.462-1.323v-8.85a1.48 1.48 0 0 0-1.462-1.41Zm-6.546-.174h.957a.383.383 0 0 0 .331-.313 1.01 1.01 0 0 1 .958-.784.992.992 0 0 1 .94.784c.031.171.174.3.348.313h.992v1.393H4.732V1.992Zm7.312 10.435c0 .383-.383.627-.766.627H2.712c-.383 0-.766-.244-.766-.627v-8.85a.783.783 0 0 1 .766-.714h1.324v.887a.366.366 0 0 0 .383.331h5.135c.2.011.374-.133.4-.33v-.888h1.324c.4.007.73.315.766.713v8.85Z"/><path fill="#7147E8" stroke="#7147E8" stroke-width=".2" d="M5.663 9.525a.283.283 0 0 0-.396-.014l-.906.863-.382-.396a.283.283 0 0 0-.397-.014.297.297 0 0 0 0 .41l.58.595c.05.056.123.087.199.085a.283.283 0 0 0 .198-.085L5.663 9.92a.269.269 0 0 0 0-.396ZM10.243 10H7.368c-.138 0-.25.167-.25.374s.112.375.25.375h2.875c.138 0 .25-.168.25-.375S10.38 10 10.243 10ZM5.663 6.526a.283.283 0 0 0-.396-.014l-.906.863-.382-.396a.283.283 0 0 0-.397-.014.297.297 0 0 0 0 .41l.58.594c.05.057.123.088.199.085a.283.283 0 0 0 .198-.085l1.104-1.047a.269.269 0 0 0 0-.396ZM10.243 7H7.368c-.138 0-.25.168-.25.375s.112.375.25.375h2.875c.138 0 .25-.168.25-.375S10.38 7 10.243 7Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" fill="none"><path fill="#7147E8" stroke="#7147E8" stroke-width=".2" d="M11.278 2.166H9.955v-.592c0-.191-.21-.278-.4-.278H8.526C8.283.599 7.674.25 6.977.25a1.584 1.584 0 0 0-1.549 1.045h-1.01c-.19 0-.382.087-.382.278v.592H2.712a1.48 1.48 0 0 0-1.462 1.41v8.85c0 .767.696 1.324 1.462 1.324h8.566c.766 0 1.462-.557 1.462-1.323v-8.85a1.48 1.48 0 0 0-1.462-1.41Zm-6.546-.174h.957a.383.383 0 0 0 .331-.313 1.01 1.01 0 0 1 .958-.784.992.992 0 0 1 .94.784c.031.171.174.3.348.313h.992v1.393H4.732V1.992Zm7.312 10.435c0 .383-.383.627-.766.627H2.712c-.383 0-.766-.244-.766-.627v-8.85a.783.783 0 0 1 .766-.714h1.324v.887a.366.366 0 0 0 .383.331h5.135c.2.011.374-.133.4-.33v-.888h1.324c.4.007.73.315.766.713v8.85Z"/><path fill="#7147E8" stroke="#7147E8" stroke-width=".2" d="M5.663 9.525a.283.283 0 0 0-.396-.014l-.906.863-.382-.396a.283.283 0 0 0-.397-.014.297.297 0 0 0 0 .41l.58.595c.05.056.123.087.199.085a.283.283 0 0 0 .198-.085L5.663 9.92a.269.269 0 0 0 0-.396ZM10.243 10H7.368c-.138 0-.25.167-.25.374s.112.375.25.375h2.875c.138 0 .25-.168.25-.375S10.38 10 10.243 10ZM5.663 6.526a.283.283 0 0 0-.396-.014l-.906.863-.382-.396a.283.283 0 0 0-.397-.014.297.297 0 0 0 0 .41l.58.594c.05.057.123.088.199.085a.283.283 0 0 0 .198-.085l1.104-1.047a.269.269 0 0 0 0-.396ZM10.243 7H7.368c-.138 0-.25.168-.25.375s.112.375.25.375h2.875c.138 0 .25-.168.25-.375S10.38 7 10.243 7Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -11,13 +11,14 @@
* limitations under the License.
*/
import { Popover } from 'antd';
import { Button, Popover, Space, Typography } from 'antd';
import { AxiosError } from 'axios';
import classNames from 'classnames';
import { t } from 'i18next';
import { isFunction, isUndefined } from 'lodash';
import React, { FC, Fragment } from 'react';
import { useHistory } from 'react-router-dom';
import { ReactComponent as IconTaskColor } from '../../../assets/svg/Task-ic.svg';
import { EntityField } from '../../../constants/Feeds.constants';
import { EntityType } from '../../../enums/entity.enum';
import { ThreadType } from '../../../generated/entity/feed/thread';
@ -157,18 +158,18 @@ const Description: FC<DescriptionProps> = ({
const getDescriptionTaskElement = () => {
return !isUndefined(tasks) ? (
<button
className="tw-w-7 tw-h-7 tw-mr-2 tw-flex-none link-text focus:tw-outline-none"
<Button
className="w-7 h-7 m-r-xs p-0"
data-testid="description-task"
type="text"
onClick={() => onThreadLinkSelect?.(tasks.entityLink, ThreadType.Task)}>
<span className="tw-flex">
<SVGIcons alt="tasks" icon={Icons.TASK_ICON} width="16px" />{' '}
<span className="tw-ml-1" data-testid="description-tasks-count">
{' '}
<Space align="center" className="w-full h-full" size={3}>
<IconTaskColor height={16} name="tasks" width={16} />
<Typography.Text data-testid="description-tasks-count">
{tasks.count}
</span>
</span>
</button>
</Typography.Text>
</Space>
</Button>
) : null;
};

View File

@ -36,6 +36,7 @@
.manage-dropdown-button:focus {
.manage-dropdown-icon {
color: @white;
font-weight: 600;
}
background-color: @manage-button-bg-primary;
}

View File

@ -121,6 +121,7 @@
"configure-dbt-model": "Configure dbt Model",
"configure-entity": "Configure {{entity}}",
"configure-glossary-term": "Configure Glossary Term",
"configure-test-case": "Configure test case",
"confirm": "Confirm",
"confirm-lowercase": "confirm",
"confirm-new-password": "Confirm New Password",
@ -243,6 +244,7 @@
"elastic-search-re-index": "ElasticsearchReindex",
"elasticsearch": "Elasticsearch",
"email": "Email",
"email-lowercase": "email",
"email-plural": "Emails",
"enable-debug-log": "Enable Debug Log",
"enable-partition": "Enable Partition",
@ -254,7 +256,9 @@
"endpoint-url-for-aws": "EndPoint URL for the AWS",
"enter": "Enter",
"enter-entity": "Enter {{entity}}",
"enter-entity-name": "Enter {{entity}} name",
"enter-field-description": "Enter {{field}} description",
"enter-last-name": "Enter last name",
"enter-name": "Enter Name",
"enter-property-description": "Enter Property Description",
"enter-property-value": "Enter Property Value",
@ -263,6 +267,7 @@
"entity-does-not-have-followers": "{{entityName}} doesn't have any followers yet",
"entity-index": "{{entity}} index",
"entity-ingestion-added-successfully": "{{entity}} Ingestion Added Successfully",
"entity-name": "{{entity}} Name",
"entity-plural": "Entities",
"entity-proportion": "{{entity}} Proportion",
"entity-service": "{{entity}} Service",
@ -292,6 +297,8 @@
"field-required": "{{field}} is required",
"field-required-plural": "{{field}} are required",
"filter-plural": "Filters",
"first": "First",
"first-lowercase": "first",
"flush-interval-secs": "Flush Interval (secs)",
"follow": "Follow",
"followed-lowercase": "followed",
@ -371,8 +378,10 @@
"kpi-name": "KPI Name",
"kpi-title": "Key Performance Indicators (KPI)",
"kpi-uppercase": "KPI",
"last": "Last",
"last-error": "Last error",
"last-failed-at": "Last Failed At",
"last-lowercase": "last",
"last-no-of-day-plural": "Last {{day}} Days",
"last-number-of-days": "Last {{numberOfDays}} days",
"last-run": "Last Run",
@ -481,6 +490,7 @@
"partitions": "Partitions",
"passed": "Passed",
"password": "Password",
"password-lowercase": "password",
"password-not-match": "Password Doesn't Match",
"password-type": "{{type}} Password",
"pause": "Pause",
@ -497,6 +507,7 @@
"pipeline-plural": "Pipelines",
"pipeline-state": "Pipeline State",
"please-enter-value": "Please enter {{name}} value",
"please-password-type-first": "Please type password first",
"please-select": "Please Select",
"plus-symbol": "+",
"policy": "Policy",
@ -613,6 +624,7 @@
"select-column-plural-to-exclude": "Select Columns to Exclude",
"select-column-plural-to-include": "Select Columns to Include",
"select-field": "Select {{field}}",
"select-team-plural": "Select teams",
"select-teams": "Select teams",
"select-to-search": "Search to Select",
"select-type": "Select type",
@ -711,6 +723,7 @@
"to-lowercase": "to",
"token-end-point": "TokenEndpoint",
"token-expiration": "Token Expiration",
"token-expired": "Token Expired",
"token-security": "Token Security",
"token-uri": "Token URI",
"topic": "Topic",
@ -806,6 +819,7 @@
"announcement-created-successfully": "Announcement created successfully!",
"announcement-invalid-start-time": "Announcement start time must be earlier than the end time.",
"are-you-sure": "Are you sure?",
"are-you-sure-delete-entity": "Are you sure you want to delete the property {{entity}}",
"are-you-sure-delete-property": "Are you sure you want to delete the property {{propertyName}}?",
"are-you-sure-delete-tag": "Are you sure you want to delete the {{type}} \"{{tagName}}\"?",
"are-you-sure-to-revoke-access": "Are you sure you want to revoke access for JWT token?",
@ -872,10 +886,13 @@
"enter-test-suite-name": "Enter test suite name",
"enter-your-registered-email": "Enter your registered email to receive password reset link",
"entity-already-exists": "{{entity}} already exists.",
"entity-delimiters-not-allowed": "Name with delimiters are not allowed",
"entity-is-not-valid": "{{entity}} is not valid",
"entity-not-contain-whitespace": "{{entity}} should not contain white space",
"entity-owned-by-name": "This entity is owned by {{entityOwner}}",
"entity-restored-error": "Error while restoring {{entity}}",
"entity-restored-success": "{{entity}} restored successfully",
"entity-size-in-between": "{{entity}} size must be between {{min}} and {{max}}",
"error-while-fetching-access-token": "Error while fetching access token.",
"failed-status-for-entity-deploy": "<0>{{entity}}</0> has been {{entityStatus}}, but failed to deploy",
"fetch-dbt-files": "These are the available sources to fetch dbt catalog and manifest files.",
@ -1052,6 +1069,7 @@
"unable-to-connect-to-your-dbt-cloud-instance": "URL to connect to your dbt cloud instance. E.g., \n https://cloud.getdbt.com or https://emea.dbt.com/",
"usage-ingestion-description": "Usage ingestion can be configured and deployed after a metadata ingestion has been set up. The usage ingestion workflow obtains the query log and table creation details from the underlying database and feeds it to OpenMetadata. Metadata and usage can have only one pipeline for a database service. Define the Query Log Duration (in days), Stage File Location, and Result Limit to start.",
"use-fqn-for-filtering-message": "Regex will be applied on fully qualified name (e.g service_name.db_name.schema_name.table_name) instead of raw name (e.g. table_name).",
"user-verified-successfully": "User Verified Successfully",
"valid-url-endpoint": "Endpoints should be valid URL",
"view-deleted-teams": "View All the Deleted Teams, which come under this Team.",
"view-sample-data": "To view Sample Data, run the Profiler Ingestion. Please refer to this doc to schedule the",

View File

@ -53,11 +53,11 @@ const AddRulePage = () => {
const breadcrumb = useMemo(
() => [
{
name: 'Settings',
name: t('label.setting-plural'),
url: getSettingPath(),
},
{
name: 'Policies',
name: t('label.policy-plural'),
url: policiesPath,
},
{
@ -66,7 +66,9 @@ const AddRulePage = () => {
},
{
name: 'Add New Rule',
name: t('label.add-new-entity', {
entity: t('label.rule'),
}),
url: '',
},
],

View File

@ -99,10 +99,10 @@ describe('Test Roles List Component', () => {
const container = await screen.findByTestId('policies-list-table');
const nameCol = await screen.findByText('Name');
const descriptionCol = await screen.findByText('Description');
const rolesCol = await screen.findByText('Roles');
const actionsCol = await screen.findByText('Actions');
const nameCol = await screen.findByText('label.name');
const descriptionCol = await screen.findByText('label.description');
const rolesCol = await screen.findByText('label.role-plural');
const actionsCol = await screen.findByText('label.action-plural');
expect(container).toBeInTheDocument();
expect(nameCol).toBeInTheDocument();

View File

@ -19,6 +19,7 @@ import { usePermissionProvider } from 'components/PermissionProvider/PermissionP
import { ResourceEntity } from 'components/PermissionProvider/PermissionProvider.interface';
import { isEmpty, isUndefined, uniqueId } from 'lodash';
import React, { FC, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import {
NO_PERMISSION_FOR_ACTION,
@ -45,6 +46,7 @@ interface PolicyListProps {
}
const PoliciesList: FC<PolicyListProps> = ({ policies, fetchPolicies }) => {
const { t } = useTranslation();
const [selectedPolicy, setSelectedPolicy] = useState<Policy>();
const { permissions } = usePermissionProvider();
@ -66,7 +68,7 @@ const PoliciesList: FC<PolicyListProps> = ({ policies, fetchPolicies }) => {
const columns: ColumnsType<Policy> = useMemo(() => {
return [
{
title: 'Name',
title: t('label.name'),
dataIndex: 'name',
width: '200px',
key: 'name',
@ -80,7 +82,7 @@ const PoliciesList: FC<PolicyListProps> = ({ policies, fetchPolicies }) => {
),
},
{
title: 'Description',
title: t('label.description'),
dataIndex: 'description',
key: 'description',
render: (_, record) => (
@ -88,7 +90,7 @@ const PoliciesList: FC<PolicyListProps> = ({ policies, fetchPolicies }) => {
),
},
{
title: 'Roles',
title: t('label.role-plural'),
dataIndex: 'roles',
width: '250px',
key: 'roles',
@ -149,7 +151,7 @@ const PoliciesList: FC<PolicyListProps> = ({ policies, fetchPolicies }) => {
},
},
{
title: 'Actions',
title: t('label.action-plural'),
dataIndex: 'actions',
width: '80px',
key: 'actions',
@ -158,7 +160,9 @@ const PoliciesList: FC<PolicyListProps> = ({ policies, fetchPolicies }) => {
<Tooltip
placement="left"
title={
deletePolicyPermission ? 'Delete' : NO_PERMISSION_FOR_ACTION
deletePolicyPermission
? t('label.delete')
: NO_PERMISSION_FOR_ACTION
}>
<Button
data-testid={`delete-action-${getEntityName(record)}`}
@ -190,9 +194,9 @@ const PoliciesList: FC<PolicyListProps> = ({ policies, fetchPolicies }) => {
<DeleteWidgetModal
afterDeleteAction={fetchPolicies}
allowSoftDelete={false}
deleteMessage={`Are you sure you want to delete ${getEntityName(
selectedPolicy
)}`}
deleteMessage={t('message.are-you-sure-delete-entity', {
entity: getEntityName(selectedPolicy),
})}
entityId={selectedPolicy.id}
entityName={getEntityName(selectedPolicy)}
entityType={EntityType.POLICY}

View File

@ -124,7 +124,11 @@ const PoliciesListPage = () => {
<Tooltip
placement="left"
title={
addPolicyPermission ? 'Add Policy' : NO_PERMISSION_FOR_ACTION
addPolicyPermission
? t('label.add-entity', {
entity: t('label.policy'),
})
: NO_PERMISSION_FOR_ACTION
}>
<Button
data-testid="add-policy"

View File

@ -18,6 +18,7 @@ import classNames from 'classnames';
import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichTextEditorPreviewer';
import Loader from 'components/Loader/Loader';
import React, { FC, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { getPolicies, getRoles } from 'rest/rolesAPIV1';
import { EntityType } from '../../../enums/entity.enum';
import { Policy } from '../../../generated/entity/policies/policy';
@ -46,6 +47,7 @@ const AddAttributeModal: FC<Props> = ({
selectedKeys,
isModalLoading,
}) => {
const { t } = useTranslation();
const [data, setData] = useState<EntityReference[]>([]);
const [searchedData, setSearchedData] = useState<EntityReference[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(false);
@ -149,7 +151,9 @@ const AddAttributeModal: FC<Props> = ({
<Col span={24}>
<Input
data-testid="search-input"
placeholder={`Search ${type}`}
placeholder={t('label.search-entity', {
entity: type,
})}
prefix={<SearchOutlined style={{ color: '#37352F4D' }} />}
onChange={(e) => handleSearch(e.target.value)}
/>

View File

@ -68,10 +68,10 @@ describe('Test Roles List Component', () => {
const container = await screen.findByTestId('roles-list-table');
const nameCol = await screen.findByText('Name');
const descriptionCol = await screen.findByText('Description');
const policiesCol = await screen.findByText('Policies');
const actionsCol = await screen.findByText('Actions');
const nameCol = await screen.findByText('label.name');
const descriptionCol = await screen.findByText('label.description');
const policiesCol = await screen.findByText('label.policy-plural');
const actionsCol = await screen.findByText('label.action-plural');
expect(container).toBeInTheDocument();
expect(nameCol).toBeInTheDocument();

View File

@ -19,6 +19,7 @@ import { usePermissionProvider } from 'components/PermissionProvider/PermissionP
import { ResourceEntity } from 'components/PermissionProvider/PermissionProvider.interface';
import { isEmpty, isUndefined, uniqueId } from 'lodash';
import React, { FC, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import {
NO_PERMISSION_FOR_ACTION,
@ -46,6 +47,7 @@ interface RolesListProps {
}
const RolesList: FC<RolesListProps> = ({ roles, fetchRoles }) => {
const { t } = useTranslation();
const [selectedRole, setSelectedRole] = useState<Role>();
const { permissions } = usePermissionProvider();
@ -67,7 +69,7 @@ const RolesList: FC<RolesListProps> = ({ roles, fetchRoles }) => {
const columns: ColumnsType<Role> = useMemo(() => {
return [
{
title: 'Name',
title: t('label.name'),
dataIndex: 'name',
width: '200px',
key: 'name',
@ -81,7 +83,7 @@ const RolesList: FC<RolesListProps> = ({ roles, fetchRoles }) => {
),
},
{
title: 'Description',
title: t('label.description'),
dataIndex: 'description',
key: 'description',
render: (_, record) => (
@ -89,7 +91,7 @@ const RolesList: FC<RolesListProps> = ({ roles, fetchRoles }) => {
),
},
{
title: 'Policies',
title: t('label.policy-plural'),
dataIndex: 'policies',
width: '250px',
key: 'policies',
@ -150,7 +152,7 @@ const RolesList: FC<RolesListProps> = ({ roles, fetchRoles }) => {
},
},
{
title: 'Actions',
title: t('label.action-plural'),
dataIndex: 'actions',
width: '80px',
key: 'actions',
@ -159,7 +161,9 @@ const RolesList: FC<RolesListProps> = ({ roles, fetchRoles }) => {
<Tooltip
placement="left"
title={
deleteRolePermission ? 'Delete' : NO_PERMISSION_FOR_ACTION
deleteRolePermission
? t('label.delete')
: NO_PERMISSION_FOR_ACTION
}>
<Button
data-testid={`delete-action-${getEntityName(record)}`}
@ -193,9 +197,9 @@ const RolesList: FC<RolesListProps> = ({ roles, fetchRoles }) => {
<DeleteWidgetModal
afterDeleteAction={fetchRoles}
allowSoftDelete={false}
deleteMessage={`Are you sure you want to delete ${getEntityName(
selectedRole
)}`}
deleteMessage={t('message.are-you-sure-delete-entity', {
entity: getEntityName(selectedRole),
})}
entityId={selectedRole.id}
entityName={getEntityName(selectedRole)}
entityType={EntityType.ROLE}

View File

@ -125,7 +125,13 @@ const RolesListPage = () => {
<PageHeader data={PAGE_HEADERS.ROLES} />
<Tooltip
placement="left"
title={addRolePermission ? 'Add Role' : NO_PERMISSION_FOR_ACTION}>
title={
addRolePermission
? t('label.add-entity', {
entity: t('label.role'),
})
: NO_PERMISSION_FOR_ACTION
}>
<Button
data-testid="add-role"
disabled={!addRolePermission}

View File

@ -60,7 +60,7 @@ const AccountActivationConfirmation = () => {
<Space align="center" direction="vertical">
<Alert
showIcon
message="User Verified Successfully"
message={t('label.user-verified-successfully')}
type="success"
/>
<div className="mt-12" onClick={handleBackToLogin}>
@ -73,7 +73,7 @@ const AccountActivationConfirmation = () => {
) : (
<div className="mt-12 w-16">
<Space align="center" direction="vertical">
<Alert showIcon message="Token Expired" type="error" />
<Alert showIcon message={t('label.token-expired')} type="error" />
<div className="mt-12">
<Typography.Link underline>
{t('label.regenerate-registration-token')}

View File

@ -67,11 +67,17 @@ const BasicSignUp = () => {
const handleLogin = () => history.push(ROUTES.SIGNIN);
const validationMessages = {
required: '${label} is required',
required: t('message.field-text-is-required', {
fieldText: '${label}',
}),
types: {
email: '${label} is not valid',
email: t('message.entity-is-not-valid', {
entity: '${label}',
}),
},
whitespace: '${label} should not contain white space',
whitespace: t('message.entity-not-contain-whitespace', {
entity: '${label}',
}),
};
return (
@ -97,25 +103,37 @@ const BasicSignUp = () => {
validateMessages={validationMessages}
onFinish={handleSubmit}>
<Form.Item
label="First Name"
label={t('label.entity-name', {
entity: t('label.first'),
})}
name="firstName"
rules={[{ whitespace: true, required: true }]}>
<Input placeholder="Enter first name" />
<Input
placeholder={t('label.enter-entity-name', {
entity: t('label.first-lowercase'),
})}
/>
</Form.Item>
<Form.Item
label="Last Name"
label={t('label.entity-name', {
entity: t('label.last'),
})}
name="lastName"
rules={[{ whitespace: true, required: true }]}>
<Input placeholder="Enter last name" />
<Input placeholder={t('label.enter-last-name')} />
</Form.Item>
<Form.Item
label="Email"
label={t('label.email')}
name="email"
rules={[{ type: 'email', required: true }]}>
<Input placeholder="Enter email" />
<Input
placeholder={t('label.enter-entity', {
entity: t('label.email-lowercase'),
})}
/>
</Form.Item>
<Form.Item
label="Password"
label={t('label.password')}
name="password"
rules={[
{
@ -126,22 +144,28 @@ const BasicSignUp = () => {
message: passwordErrorMessage,
},
]}>
<Input.Password placeholder="Enter password" />
<Input.Password
placeholder={t('label.enter-entity', {
entity: t('label.password-lowercase'),
})}
/>
</Form.Item>
<Form.Item
label="Confirm Password"
label={t('label.password-type', {
type: t('label.confirm'),
})}
name="confirmPassword"
rules={[
{
validator: (_, value) => {
if (isEmpty(password)) {
return Promise.reject(
'Please type password first'
t('label.please-password-type-first')
);
}
if (value !== password) {
return Promise.reject(
"Password doesn't match"
t('label.password-not-match')
);
}
@ -149,7 +173,9 @@ const BasicSignUp = () => {
},
},
]}>
<Input.Password placeholder="Confirm your password" />
<Input.Password
placeholder={t('label.confirm-password')}
/>
</Form.Item>
<Button

View File

@ -468,11 +468,19 @@ const TagsPage = () => {
if (errorDataTag || forceSet) {
const errData: { [key: string]: string } = {};
if (!data.name.trim()) {
errData['name'] = 'Name is required';
errData['name'] = t('label.field-required', {
field: t('label.name'),
});
} else if (delimiterRegex.test(data.name)) {
errData['name'] = 'Name with delimiters are not allowed';
errData['name'] = t('message.entity-delimiters-not-allowed', {
entity: t('label.name'),
});
} else if (data.name.length < 2 || data.name.length > 64) {
errData['name'] = 'Name size must be between 2 and 64';
errData['name'] = t('message.entity-size-in-between', {
entity: t('label.name'),
max: 64,
min: 2,
});
}
setErrorDataTag(errData);

View File

@ -20,6 +20,9 @@
.w-6 {
width: 1.5rem;
}
.w-7 {
width: 28px;
}
.w-8 {
width: 32px;
}