UI : Added locailzation (#10151)

* added locailzation

* minor changes

* fix unit test issue
This commit is contained in:
Ashish Gupta 2023-02-09 14:26:28 +05:30 committed by GitHub
parent abbc5e2686
commit b8a6f549e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 249 additions and 103 deletions

View File

@ -14,6 +14,7 @@
import { Button, Tooltip } from 'antd';
import Table, { ColumnsType } from 'antd/lib/table';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { NO_PERMISSION_FOR_ACTION } from '../../constants/HelperTextUtil';
import { EntityType } from '../../enums/entity.enum';
@ -37,10 +38,11 @@ const ListEntities = ({
onDelete: (record: EntityReference) => void;
hasAccess: boolean;
}) => {
const { t } = useTranslation();
const columns: ColumnsType<EntityReference> = useMemo(() => {
return [
{
title: 'Name',
title: t('label.name'),
dataIndex: 'name',
width: '200px',
key: 'name',
@ -71,7 +73,7 @@ const ListEntities = ({
},
},
{
title: 'Description',
title: t('label.description'),
dataIndex: 'description',
key: 'description',
render: (_, record) => (
@ -79,7 +81,7 @@ const ListEntities = ({
),
},
{
title: 'Actions',
title: t('label.action-plural'),
dataIndex: 'actions',
width: '80px',
key: 'actions',
@ -87,7 +89,7 @@ const ListEntities = ({
return (
<Tooltip
placement="bottomRight"
title={hasAccess ? 'Remove' : NO_PERMISSION_FOR_ACTION}>
title={hasAccess ? t('label.remove') : NO_PERMISSION_FOR_ACTION}>
<Button
data-testid={`remove-action-${getEntityName(record)}`}
disabled={!hasAccess}

View File

@ -11,6 +11,7 @@
* limitations under the License.
*/
import { t } from 'i18next';
import { isEmpty, isUndefined } from 'lodash';
import { Team } from '../../generated/entity/teams/team';
import { Paging } from '../../generated/type/paging';
@ -25,31 +26,31 @@ export const getTabs = (
) => {
const tabs = {
teams: {
name: 'Teams',
name: t('label.team-plural'),
isProtected: false,
position: 1,
count: teamsCount,
},
users: {
name: 'Users',
name: t('label.user-plural'),
isProtected: false,
position: 2,
count: teamUserPagin?.total,
},
assets: {
name: 'Assets',
name: t('label.asset-plural'),
isProtected: false,
position: 3,
count: filterEntityAssets(currentTeam?.owns || []).length,
},
roles: {
name: 'Roles',
name: t('label.role-plural'),
isProtected: false,
position: 4,
count: currentTeam?.defaultRoles?.length,
},
policies: {
name: 'Policies',
name: t('label.policy-plural'),
isProtected: false,
position: 5,
count: currentTeam?.policies?.length,

View File

@ -79,12 +79,12 @@ describe('Team Hierarchy page', () => {
});
const table = await screen.findByTestId('team-hierarchy-table');
const teamsColumn = await screen.findByText('Teams');
const typeColumn = await screen.findByText('Type');
const subTeamsColumn = await screen.findByText('Sub Teams');
const usersColumn = await screen.findByText('Users');
const assetCountColumn = await screen.findByText('Asset Count');
const descriptionColumn = await screen.findByText('Description');
const teamsColumn = await screen.findByText('label.team-plural');
const typeColumn = await screen.findByText('label.type');
const subTeamsColumn = await screen.findByText('label.sub-team-plural');
const usersColumn = await screen.findByText('label.user-plural');
const assetCountColumn = await screen.findByText('label.asset-count');
const descriptionColumn = await screen.findByText('label.description');
const rows = await screen.findAllByRole('row');
expect(table).toBeInTheDocument();

View File

@ -49,7 +49,7 @@ const TeamHierarchy: FC<TeamHierarchyProps> = ({
const columns: ColumnsType<Team> = useMemo(() => {
return [
{
title: 'Teams',
title: t('label.team-plural'),
dataIndex: 'teams',
key: 'teams',
render: (_, record) => (
@ -61,30 +61,30 @@ const TeamHierarchy: FC<TeamHierarchyProps> = ({
),
},
{
title: 'Type',
title: t('label.type'),
dataIndex: 'teamType',
key: 'teamType',
},
{
title: 'Sub Teams',
title: t('label.sub-team-plural'),
dataIndex: 'childrenCount',
key: 'subTeams',
render: (childrenCount: number) => childrenCount ?? '--',
},
{
title: 'Users',
title: t('label.user-plural'),
dataIndex: 'userCount',
key: 'users',
render: (userCount: number) => userCount ?? '--',
},
{
title: 'Asset Count',
title: t('label.asset-count'),
dataIndex: 'owns',
key: 'owns',
render: (owns) => owns.length,
},
{
title: 'Description',
title: t('label.description'),
dataIndex: 'description',
key: 'description',
render: (description: string) => description || '--',

View File

@ -11,30 +11,11 @@
* limitations under the License.
*/
import { ONBOARDING_STEPS_DATA } from 'constants/Onboarding.constants';
import { t } from 'i18next';
import { uniqueId } from 'lodash';
import React, { FC } from 'react';
const stepsData = [
{
step: 1,
title: 'Explore Data',
description: 'Look at the popular data assets in your organization.',
},
{
step: 2,
title: 'Claim Ownership',
description:
'Data works well when it is owned. Take a look at the data assets that you own and claim ownership.',
},
{
step: 3,
title: 'Stay Up-to-date',
description:
'Follow the datasets that you frequently use to stay informed about it.',
},
];
const Onboarding: FC = () => {
return (
<div
@ -48,7 +29,7 @@ const Onboarding: FC = () => {
{t('message.om-description')}
</div>
<div className="tw-grid tw-grid-cols-3 tw-gap-3 tw-mt-5">
{stepsData.map((data) => (
{ONBOARDING_STEPS_DATA.map((data) => (
<div
className="tw-card tw-flex tw-flex-col tw-justify-between tw-p-5"
key={uniqueId()}>
@ -62,11 +43,11 @@ const Onboarding: FC = () => {
<h6
className="tw-text-base tw-text-grey-body tw-font-medium"
data-testid="service-name">
{data.title}
{t(data.title)}
</h6>
<p className="tw-text-grey-body tw-pb-1 tw-text-sm tw-mb-5">
{data.description}
{t(data.description)}
</p>
</div>
</div>

View File

@ -0,0 +1,30 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const ONBOARDING_STEPS_DATA = [
{
step: 1,
title: 'label.explore-data',
description: 'message.onboarding-explore-data-description',
},
{
step: 2,
title: 'label.claim-ownership',
description: 'message.onboarding-claim-ownership-description',
},
{
step: 3,
title: 'label.stay-up-to-date',
description: 'message.onboarding-stay-up-to-date-description',
},
];

View File

@ -20,7 +20,6 @@
"add-custom-entity-property": "Add Custom {{entity}} Property",
"add-deploy": "Add & Deploy",
"add-entity": "Add {{entity}}",
"add-glossary": "Add Glossary",
"add-new-entity": "Add New {{entity}}",
"add-workflow-ingestion": "Add {{workflow}} Ingestion",
"added": "Added",
@ -29,6 +28,7 @@
"adding-new-classification": "Adding New Classification",
"adding-new-entity-is-easy-just-give-it-a-spin": "Adding a new {{entity}} is easy, just give it a spin!",
"adding-new-tag": "Adding new tag on {{categoryName}}",
"address": "Address",
"admin": "Admin",
"admin-plural": "Admins",
"advanced-entity": "Advanced {{entity}}",
@ -50,6 +50,7 @@
"applied-advanced-search": "Applied Advanced Search",
"apply": "Apply",
"as-lowercase": "as",
"asset-count": "Asset Count",
"asset-lowercase": "asset",
"asset-plural": "Assets",
"assigned-entity": "Assigned {{entity}}",
@ -87,6 +88,7 @@
"chart-plural": "Charts",
"chart-type": "Chart Type",
"check-status": "Check status",
"claim-ownership": "Claim Ownership",
"classification": "Classification",
"classification-lowercase": "classification",
"classification-plural": "Classifications",
@ -122,6 +124,7 @@
"confirm": "Confirm",
"confirm-lowercase": "confirm",
"confirm-new-password": "Confirm New Password",
"confirm-password": "Confirm your password",
"connection": "Connection",
"connection-details": "Connection Details",
"connection-entity": "Connection {{entity}}",
@ -256,6 +259,7 @@
"enter-property-value": "Enter Property Value",
"enter-type-password": "Enter {{type}} Password",
"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-plural": "Entities",
"entity-proportion": "{{entity}} Proportion",
@ -269,6 +273,7 @@
"execution-plural": "Executions",
"expand-all": "Expand All",
"explore": "Explore",
"explore-data": "Explore Data",
"explore-now": "Explore Now",
"export": "Export",
"export-glossary-terms": "Export glossary terms",
@ -531,6 +536,7 @@
"recreate-index-plural": "Recreate Indexes",
"refer-to-our": "Refer to our",
"reference-plural": "References",
"refresh-log": "Refresh log",
"regenerate-registration-token": "Regenerate registration token",
"region-name": "Region Name",
"registry": "Registry",
@ -601,6 +607,7 @@
"select-column-plural-to-include": "Select Columns to Include",
"select-field": "Select {{field}}",
"select-teams": "Select teams",
"select-to-search": "Search to Select",
"select-type": "Select type",
"send-now": "Send now",
"send-to": "Send to",
@ -636,10 +643,13 @@
"started-following": "Started following",
"starting": "Starting",
"status": "Status",
"stay-up-to-date": "Stay Up-to-date",
"sub-team-plural": "Sub Teams",
"submit": "Submit",
"success": "Success",
"successfully-uploaded": "Successfully Uploaded",
"suggest": "Suggest",
"suggest-entity": "Suggest {{entity}}",
"suggestion": "Suggestion",
"suggestion-lowercase-plural": "suggestions",
"suite": "Suite",
@ -659,8 +669,10 @@
"target": "Target",
"target-column": "Target Column",
"task": "Task",
"task-entity": "Task {{entity}}",
"task-lowercase": "task",
"task-plural": "Tasks",
"task-title": "Task #{{title}}",
"team": "Team",
"team-plural": "Teams",
"team-plural-lowercase": "teams",
@ -696,6 +708,7 @@
"topic-plural": "Topics",
"topics": "Topics",
"total-entity": "Total {{entity}}",
"total-index-sent": " Total index sent",
"tour": "Tour",
"tracking": "Tracking",
"tree": "Tree",
@ -752,7 +765,8 @@
"webhook-display-text": "Webhook {{displayText}}",
"welcome-to-open-metadata": "Welcome to OpenMetadata!",
"whats-new": "What's New",
"yes": "Yes"
"yes": "Yes",
"your-entity": "Your {{entity}}"
},
"message": {
"access-to-collaborate": "Allow open access for anyone to join the team, view data, and collaborate.",
@ -949,6 +963,9 @@
"no-version-type-available": "No {{type}} version available",
"not-followed-anything": "You have not followed anything yet.",
"om-description": "Centralized metadata store, to discover, collaborate and get your data right.",
"onboarding-claim-ownership-description": "Data works well when it is owned. Take a look at the data assets that you own and claim ownership.",
"onboarding-explore-data-description": "Look at the popular data assets in your organization.",
"onboarding-stay-up-to-date-description": "Follow the datasets that you frequently use to stay informed about it.",
"optional-configuration-update-description-dbt": "Optional configuration to update the description from dbt or not",
"page-is-not-available": "The page you are looking for is not available",
"path-of-the-dbt-files-stored": "Path of the folder where the dbt files are stored",
@ -1055,6 +1072,7 @@
"no-owned-entities": "You have not owned anything yet.",
"no-query-available": "No query available.",
"no-task-available": "No task data is available.",
"no-task-creation-without-assignee": "Cannot create a task without assignee",
"please-add-description": "Empty description is not accepted. Please add a description.",
"please-add-tags": "An empty tag list is not accepted. Please add a tag.",
"task-closed-successfully": "Task closed successfully.",

View File

@ -115,11 +115,13 @@ const AddGlossaryPage: FunctionComponent = () => {
useEffect(() => {
setSlashedBreadcrumb([
{
name: 'Glossary',
name: t('label.glossary'),
url: getGlossaryPath(),
},
{
name: 'Add Glossary',
name: t('label.add-entity', {
entity: t('label.glossary'),
}),
url: '',
activeTitle: true,
},

View File

@ -112,13 +112,13 @@ const CustomEntityDetailV1 = () => {
return [
{
name: 'Custom Properties',
name: t('label.custom-property-plural'),
isProtected: false,
position: 1,
count: (customProperties || []).length,
},
{
name: 'Schema',
name: t('label.schema'),
isProtected: false,
position: 2,
},

View File

@ -152,7 +152,7 @@ const ElasticSearchIndexPage = () => {
disabled={batchLoading}
icon={<ReloadOutlined />}
size="small"
title="Refresh log"
title={t('label.refresh-log')}
onClick={fetchBatchReIndexedData}
/>
<Button
@ -167,7 +167,7 @@ const ElasticSearchIndexPage = () => {
}
loading={batchLoading}
size="small"
title="ElasticSearch">
title={t('label.elasticsearch')}>
<Row gutter={[16, 8]}>
<Col span={24}>
<Space wrap direction="horizontal" size={0}>
@ -215,14 +215,18 @@ const ElasticSearchIndexPage = () => {
className="request-badge running"
count={batchJobData?.stats?.total}
overflowCount={99999999}
title={`Total index sent: ${batchJobData?.stats?.total}`}
title={`${t('label.total-index-sent')}: ${
batchJobData?.stats?.total
}`}
/>
<Badge
className="request-badge success"
count={batchJobData?.stats?.success}
overflowCount={99999999}
title={`Success index: ${batchJobData?.stats?.success}`}
title={`${t('label.entity-index', {
entity: t('label.success'),
})}: ${batchJobData?.stats?.success}`}
/>
<Badge
@ -230,7 +234,9 @@ const ElasticSearchIndexPage = () => {
className="request-badge failed"
count={batchJobData?.stats?.failed}
overflowCount={99999999}
title={`Failed index: ${batchJobData?.stats?.failed}`}
title={`${t('label.entity-index', {
entity: t('label.failed'),
})}: ${batchJobData?.stats?.failed}`}
/>
</Space>
) : (
@ -309,13 +315,13 @@ const ElasticSearchIndexPage = () => {
disabled={streamLoading}
icon={<ReloadOutlined />}
size="small"
title="Refresh log"
title={t('label.refresh-log')}
onClick={fetchStreamReIndexedData}
/>
}
loading={streamLoading}
size="small"
title="ElasticSearch">
title={t('label.elasticsearch')}>
<Row gutter={[16, 8]}>
<Col span={24}>
<Space direction="horizontal" size={16}>

View File

@ -163,12 +163,16 @@ const RequestDescription = () => {
};
postThread(data)
.then((res) => {
showSuccessToast('Task Created Successfully');
showSuccessToast(
t('server.create-entity-success', {
entity: t('label.task'),
})
);
history.push(getTaskDetailPath(res.task?.id.toString() ?? ''));
})
.catch((err: AxiosError) => showErrorToast(err));
} else {
showErrorToast('Cannot create a task without assignee');
showErrorToast(t('server.no-task-creation-without-assignee'));
}
};
@ -201,7 +205,13 @@ const RequestDescription = () => {
<TitleBreadcrumb
titleLinks={[
...getBreadCrumbList(entityData, entityType as EntityType),
{ name: 'Create Task', activeTitle: true, url: '' },
{
name: t('label.create-entity', {
entity: t('label.task'),
}),
activeTitle: true,
url: '',
},
]}
/>
<div className="tw-grid tw-grid-cols-3 tw-gap-x-2">
@ -209,14 +219,26 @@ const RequestDescription = () => {
className="tw-col-span-2"
key="request-description"
style={{ ...cardStyles }}
title="Create Task">
title={t('label.create-entity', {
entity: t('label.task'),
})}>
<Form form={form} layout="vertical" onFinish={onCreateTask}>
<Form.Item data-testid="title" label="Title:" name="title">
<Input placeholder="Task title" style={{ margin: '4px 0px' }} />
<Form.Item
data-testid="title"
label={`${t('label.task-entity', {
entity: t('label.title'),
})}:`}
name="title">
<Input
placeholder={t('label.task-entity', {
entity: t('label.title'),
})}
style={{ margin: '4px 0px' }}
/>
</Form.Item>
<Form.Item
data-testid="assignees"
label="Assignees:"
label={`${t('label.assignee-plural')}:`}
name="assignees">
<Assignees
assignees={assignees}
@ -227,12 +249,16 @@ const RequestDescription = () => {
</Form.Item>
<Form.Item
data-testid="description-label"
label="Suggest description:"
label={`${t('label.suggest-entity', {
entity: t('label.description'),
})}:`}
name="SuggestDescription">
<RichTextEditor
className="tw-my-0"
initialValue=""
placeHolder="Suggest description"
placeHolder={t('label.suggest-entity', {
entity: t('label.description'),
})}
ref={markdownRef}
style={{ marginTop: '4px' }}
onTextChange={onSuggestionChange}

View File

@ -151,12 +151,16 @@ const RequestTag = () => {
};
postThread(data)
.then((res) => {
showSuccessToast('Task Created Successfully');
showSuccessToast(
t('server.create-entity-success', {
entity: t('label.task'),
})
);
history.push(getTaskDetailPath(res.task?.id.toFixed() ?? ''));
})
.catch((err: AxiosError) => showErrorToast(err));
} else {
showErrorToast('Cannot create a task without assignee');
showErrorToast(t('server.no-task-creation-without-assignee'));
}
};
@ -189,7 +193,13 @@ const RequestTag = () => {
<TitleBreadcrumb
titleLinks={[
...getBreadCrumbList(entityData, entityType as EntityType),
{ name: 'Create Task', activeTitle: true, url: '' },
{
name: t('label.create-entity', {
entity: t('label.task'),
}),
activeTitle: true,
url: '',
},
]}
/>
<div className="tw-grid tw-grid-cols-3 tw-gap-x-2">
@ -197,14 +207,26 @@ const RequestTag = () => {
className="tw-col-span-2"
key="request-tags"
style={{ ...cardStyles }}
title="Create Task">
title={t('label.create-entity', {
entity: t('label.task'),
})}>
<Form form={form} layout="vertical" onFinish={onCreateTask}>
<Form.Item data-testid="title" label="Title:" name="title">
<Input placeholder="Task title" style={{ margin: '4px 0px' }} />
<Form.Item
data-testid="title"
label={`${t('label.task-entity', {
entity: t('label.title'),
})}:`}
name="title">
<Input
placeholder={`${t('label.task-entity', {
entity: t('label.title'),
})}`}
style={{ margin: '4px 0px' }}
/>
</Form.Item>
<Form.Item
data-testid="assignees"
label="Assignees:"
label={`${t('label.assignee-plural')}:`}
name="assignees">
<Assignees
assignees={assignees}
@ -215,7 +237,9 @@ const RequestTag = () => {
</Form.Item>
<Form.Item
data-testid="tags-label"
label="Suggest tags:"
label={`${t('label.suggest-entity', {
entity: t('label.tag-plural'),
})}:`}
name="suggestTags">
<TagSuggestion
selectedTags={suggestion}

View File

@ -535,7 +535,9 @@ const TaskDetailPage = () => {
titleLinks={[
...getBreadCrumbList(entityData, entityType as EntityType),
{
name: `Task #${taskDetail.task?.id}`,
name: t('label.task-title', {
title: taskDetail.task?.id,
}),
activeTitle: true,
url: '',
},
@ -549,7 +551,9 @@ const TaskDetailPage = () => {
<p
className="tw-text-base tw-font-medium tw-mb-4"
data-testid="task-title">
{`Task #${taskId}`} {taskDetail.message}
{t('label.task-title', {
title: `${taskId} ${taskDetail.message}`,
})}
</p>
<div className="tw-flex tw-mb-4" data-testid="task-metadata">
<TaskStatus
@ -728,7 +732,7 @@ const TaskDetailPage = () => {
theme="light"
width={600}>
<Tabs className="ant-tabs-custom-line" onChange={onTabChange}>
<TabPane key={PanelTab.TASKS} tab="Task">
<TabPane key={PanelTab.TASKS} tab={t('label.task')}>
{!isEmpty(taskFeedDetail) ? (
<div id="task-feed">
<FeedPanelBody
@ -745,7 +749,9 @@ const TaskDetailPage = () => {
) : null}
</TabPane>
<TabPane key={PanelTab.CONVERSATIONS} tab="Conversations">
<TabPane
key={PanelTab.CONVERSATIONS}
tab={t('label.conversation-plural')}>
{!isEmpty(taskFeedDetail) ? (
<ActivityThreadPanelBody
className="tw-p-0"

View File

@ -165,12 +165,16 @@ const UpdateDescription = () => {
};
postThread(data)
.then((res) => {
showSuccessToast('Task Created Successfully');
showSuccessToast(
t('server.create-entity-success', {
entity: t('label.task'),
})
);
history.push(getTaskDetailPath(res.task?.id.toString() ?? ''));
})
.catch((err: AxiosError) => showErrorToast(err));
} else {
showErrorToast('Cannot create a task without assignee');
showErrorToast(t('server.no-task-creation-without-assignee'));
}
};
@ -207,7 +211,13 @@ const UpdateDescription = () => {
<TitleBreadcrumb
titleLinks={[
...getBreadCrumbList(entityData, entityType as EntityType),
{ name: 'Create Task', activeTitle: true, url: '' },
{
name: t('label.create-entity', {
entity: t('label.task'),
}),
activeTitle: true,
url: '',
},
]}
/>
<div className="tw-grid tw-grid-cols-3 tw-gap-x-2">
@ -215,14 +225,24 @@ const UpdateDescription = () => {
className="tw-col-span-2"
key="update-description"
style={{ ...cardStyles }}
title="Create Task">
title={t('label.create-entity', {
entity: t('label.task'),
})}>
<Form form={form} layout="vertical" onFinish={onCreateTask}>
<Form.Item data-testid="title" label="Title:" name="title">
<Input placeholder="Task title" style={{ margin: '4px 0px' }} />
<Form.Item
data-testid="title"
label={`${t('label.title')}:`}
name="title">
<Input
placeholder={t('label.task-entity', {
entity: t('label.title'),
})}
style={{ margin: '4px 0px' }}
/>
</Form.Item>
<Form.Item
data-testid="assignees"
label="Assignees:"
label={`${t('label.assignee-plural')}:`}
name="assignees">
<Assignees
assignees={assignees}
@ -235,7 +255,7 @@ const UpdateDescription = () => {
{currentDescription && (
<Form.Item
data-testid="description-tabs"
label="Description:"
label={`${t('label.description')}:`}
name="description">
<DescriptionTabs
description={currentDescription}

View File

@ -164,12 +164,16 @@ const UpdateTag = () => {
};
postThread(data)
.then((res) => {
showSuccessToast('Task Created Successfully');
showSuccessToast(
t('server.create-entity-success', {
entity: t('label.task'),
})
);
history.push(getTaskDetailPath(res.task?.id.toString() ?? ''));
})
.catch((err: AxiosError) => showErrorToast(err));
} else {
showErrorToast('Cannot create a task without assignee');
showErrorToast(t('server.no-task-creation-without-assignee'));
}
};
@ -207,7 +211,13 @@ const UpdateTag = () => {
<TitleBreadcrumb
titleLinks={[
...getBreadCrumbList(entityData, entityType as EntityType),
{ name: 'Create Task', activeTitle: true, url: '' },
{
name: t('label.create-entity', {
entity: t('label.task'),
}),
activeTitle: true,
url: '',
},
]}
/>
<div className="tw-grid tw-grid-cols-3 tw-gap-x-2">
@ -215,14 +225,24 @@ const UpdateTag = () => {
className="tw-col-span-2"
key="update-tags"
style={{ ...cardStyles }}
title="Create Task">
title={t('label.create-entity', {
entity: t('label.task'),
})}>
<Form form={form} layout="vertical" onFinish={onCreateTask}>
<Form.Item data-testid="title" label="Title:" name="title">
<Input placeholder="Task title" style={{ margin: '4px 0px' }} />
<Form.Item
data-testid="title"
label={`${t('label.title')}:`}
name="title">
<Input
placeholder={t('label.task-entity', {
entity: t('label.title'),
})}
style={{ margin: '4px 0px' }}
/>
</Form.Item>
<Form.Item
data-testid="assignees"
label="Assignees:"
label={`${t('label.assignee-plural')}:`}
name="assignees">
<Assignees
assignees={assignees}
@ -235,7 +255,9 @@ const UpdateTag = () => {
{currentTags.length ? (
<Form.Item
data-testid="tags-label"
label="Update tags:"
label={t('label.update-entity', {
entity: t('label.tag-plural'),
})}
name="UpdateTags">
<TagsTabs
suggestedTags={suggestion}

View File

@ -13,6 +13,7 @@
import { Select } from 'antd';
import { UserTag } from 'components/common/UserTag/UserTag.component';
import { t } from 'i18next';
import React, { FC } from 'react';
import { Option } from '../TasksPage.interface';
import './Assignee.less';
@ -46,7 +47,7 @@ const Assignees: FC<Props> = ({ assignees, onSearch, onChange, options }) => {
filterOption={false}
mode="multiple"
notFoundContent={null}
placeholder="Search to Select"
placeholder={t('label.select-to-search')}
showArrow={false}
value={assignees.length ? assignees : undefined}
onChange={handleOnChange}

View File

@ -89,7 +89,7 @@ export const DescriptionTabs = ({
className="tw-my-0"
height="208px"
initialValue={suggestion}
placeHolder={placeHolder ?? 'Update description'}
placeHolder={placeHolder ?? t('label.update-description')}
ref={markdownRef}
onTextChange={onChange}
/>

View File

@ -120,7 +120,9 @@ const DescriptionTask: FC<DescriptionTaskProps> = ({
<RichTextEditor
height="208px"
initialValue={suggestion}
placeHolder="Add description"
placeHolder={t('label.add-entity', {
entity: t('label.description'),
})}
style={{ marginTop: '0px' }}
onTextChange={onSuggestionChange}
/>

View File

@ -13,6 +13,7 @@
import { Select } from 'antd';
import { AxiosError } from 'axios';
import { t } from 'i18next';
import { isEmpty, isEqual } from 'lodash';
import React, { useEffect, useState } from 'react';
import { getTagSuggestions } from 'rest/miscAPI';
@ -100,7 +101,7 @@ const TagSuggestion: React.FC<Props> = ({ onChange, selectedTags }) => {
filterOption={false}
mode="multiple"
notFoundContent={null}
placeholder="Search to Select"
placeholder={t('label.select-to-search')}
showArrow={false}
value={!isEmpty(selectedOptions()) ? selectedOptions() : undefined}
onChange={handleOnChange}

View File

@ -27,7 +27,7 @@ const PageNotFound = () => {
className="page-not-found-container tw-relative"
data-testid="no-page-found">
<div className="tw-flex-center tw-hw-full tw-absolute tw-inset-0">
<img alt="not found" src={notFoundNumber} />
<img alt={t('label.not-found')} src={notFoundNumber} />
</div>
<div className="tw-flex tw-hw-full tw-absolute tw-inset-0">
<div className="tw-hw-full tw-flex-center">
@ -53,7 +53,7 @@ const PageNotFound = () => {
</div>
</div>
<div className="tw-hw-full tw-flex-center">
<img alt="not found" src={notFoundImage} />
<img alt={t('label.not-found')} src={notFoundImage} />
</div>
</div>
</div>

View File

@ -146,7 +146,9 @@ const SignUp = () => {
data-testid="full-name-input"
id="displayName"
name="displayName"
placeholder="Your Full name"
placeholder={t('label.your-entity', {
entity: t('label.full-name'),
})}
type="text"
value={details.displayName}
onChange={onChangeHandler}
@ -168,7 +170,7 @@ const SignUp = () => {
data-testid="username-input"
id="name"
name="name"
placeholder="Username"
placeholder={t('label.username')}
type="text"
value={details.name}
onChange={onChangeHandler}
@ -190,7 +192,9 @@ const SignUp = () => {
data-testid="email-input"
id="email"
name="email"
placeholder="Your email address"
placeholder={t('label.your-entity', {
entity: `${t('label.email')} ${t('label.address')}`,
})}
type="email"
value={details.email}
onChange={onChangeHandler}