Skip to content

Commit 915f06a

Browse files
committed
feature: Improve the internationalization of dataset pages
1 parent 8205e8a commit 915f06a

7 files changed

Lines changed: 212 additions & 120 deletions

File tree

frontend/src/components/AddTagPopover.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Button, Input, Popover, theme, Tag, Empty } from "antd";
22
import { PlusOutlined } from "@ant-design/icons";
33
import { useEffect, useMemo, useState } from "react";
4+
import { useTranslation } from "react-i18next";
45

56
interface Tag {
67
id: number;
@@ -22,6 +23,7 @@ export default function AddTagPopover({
2223
onCreateAndTag,
2324
}: AddTagPopoverProps) {
2425
const { token } = theme.useToken();
26+
const { t } = useTranslation();
2527
const [showPopover, setShowPopover] = useState(false);
2628

2729
const [newTag, setNewTag] = useState("");
@@ -68,12 +70,12 @@ export default function AddTagPopover({
6870
content={
6971
<div className="space-y-4 w-[300px]">
7072
<h4 className="font-medium border-b pb-2 border-gray-100">
71-
添加标签
73+
{t("tagManagement.addTag")}
7274
</h4>
7375
{/* Available Tags */}
7476
{availableTags?.length ? (
7577
<div className="space-y-2">
76-
<h5 className="text-sm">选择现有标签</h5>
78+
<h5 className="text-sm">{t("tagManagement.selectExistingTags")}</h5>
7779
<div className="max-h-32 overflow-y-auto space-y-1">
7880
{availableTags.map((tag) => (
7981
<span
@@ -91,15 +93,15 @@ export default function AddTagPopover({
9193
</div>
9294
</div>
9395
) : (
94-
<Empty description="没有可用标签,请先创建标签。" />
96+
<Empty description={t("tagManagement.noAvailableTags")} />
9597
)}
9698

9799
{/* Create New Tag */}
98100
<div className="space-y-2 border-t border-gray-100 pt-3">
99-
<h5 className="text-sm">创建新标签</h5>
101+
<h5 className="text-sm">{t("tagManagement.createNewTag")}</h5>
100102
<div className="flex gap-2">
101103
<Input
102-
placeholder="输入新标签名称..."
104+
placeholder={t("tagManagement.newTagNamePlaceholder")}
103105
value={newTag}
104106
onChange={(e) => setNewTag(e.target.value)}
105107
className="h-8 text-sm"
@@ -109,13 +111,13 @@ export default function AddTagPopover({
109111
disabled={!newTag.trim()}
110112
type="primary"
111113
>
112-
添加
114+
{t("tagManagement.createTag")}
113115
</Button>
114116
</div>
115117
</div>
116118

117119
<Button block onClick={() => setShowPopover(false)}>
118-
取消
120+
{t("tagManagement.cancel")}
119121
</Button>
120122
</div>
121123
}
@@ -126,7 +128,7 @@ export default function AddTagPopover({
126128
className="cursor-pointer"
127129
onClick={() => setShowPopover(true)}
128130
>
129-
添加标签
131+
{t("tagManagement.addTag")}
130132
</Tag>
131133
</Popover>
132134
</>

frontend/src/components/business/TagManagement.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Drawer, Input, Button, App } from "antd";
33
import { PlusOutlined } from "@ant-design/icons";
44
import { Edit, Save, TagIcon, X, Trash } from "lucide-react";
55
import { TagItem } from "@/pages/DataManagement/dataset.model";
6+
import { useTranslation } from "react-i18next";
67

78
interface CustomTagProps {
89
isEditable?: boolean;
@@ -105,6 +106,7 @@ const TagManager: React.FC = ({
105106
}) => {
106107
const [showTagManager, setShowTagManager] = useState(false);
107108
const { message } = App.useApp();
109+
const { t } = useTranslation();
108110
const [tags, setTags] = useState<{ id: number; name: string }[]>([]);
109111
const [newTag, setNewTag] = useState("");
110112
const [editingTag, setEditingTag] = useState<string | null>(null);
@@ -117,7 +119,7 @@ const TagManager: React.FC = ({
117119
const { data } = await onFetch?.();
118120
setTags(data || []);
119121
} catch (e) {
120-
message.error("获取标签失败");
122+
message.error(t("tagManagement.messages.fetchFailed"));
121123
}
122124
};
123125

@@ -129,9 +131,9 @@ const TagManager: React.FC = ({
129131
});
130132
fetchTags();
131133
setNewTag("");
132-
message.success("标签添加成功");
134+
message.success(t("tagManagement.messages.addSuccess"));
133135
} catch (error) {
134-
message.error("添加标签失败");
136+
message.error(t("tagManagement.messages.addFailed"));
135137
}
136138
};
137139

@@ -140,19 +142,19 @@ const TagManager: React.FC = ({
140142
try {
141143
await onDelete?.(tag.id);
142144
fetchTags();
143-
message.success("标签删除成功");
145+
message.success(t("tagManagement.messages.deleteSuccess"));
144146
} catch (error) {
145-
message.error("删除标签失败");
147+
message.error(t("tagManagement.messages.deleteFailed"));
146148
}
147149
};
148150

149151
const updateTag = async (oldTag: TagItem, newTag: string) => {
150152
try {
151153
await onUpdate?.({ ...oldTag, name: newTag });
152154
fetchTags();
153-
message.success("标签更新成功");
155+
message.success(t("tagManagement.messages.updateSuccess"));
154156
} catch (error) {
155-
message.error("更新标签失败");
157+
message.error(t("tagManagement.messages.updateFailed"));
156158
}
157159
};
158160

@@ -192,19 +194,19 @@ const TagManager: React.FC = ({
192194
icon={<TagIcon className="w-4 h-4 mr-2" />}
193195
onClick={() => setShowTagManager(true)}
194196
>
195-
标签管理
197+
{t("tagManagement.manageTags")}
196198
</Button>
197199
<Drawer
198200
open={showTagManager}
199201
onClose={() => setShowTagManager(false)}
200-
title="标签管理"
202+
title={t("tagManagement.manageTags")}
201203
width={500}
202204
>
203205
<div className="space-y-4 flex-overflow">
204206
{/* Add New Tag */}
205207
<div className="flex gap-2">
206208
<Input
207-
placeholder="输入标签名称..."
209+
placeholder={t("tagManagement.tagNamePlaceholder")}
208210
value={newTag}
209211
allowClear
210212
onChange={(e) => setNewTag(e.target.value)}
@@ -220,7 +222,7 @@ const TagManager: React.FC = ({
220222
disabled={!newTag.trim()}
221223
icon={<PlusOutlined />}
222224
>
223-
添加
225+
{t("tagManagement.createTag")}
224226
</Button>
225227
</div>
226228

frontend/src/i18n/locales/en/common.json

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -206,17 +206,17 @@
206206
"messages": {
207207
"loadTemplatesFailed": "Failed to load collection templates",
208208
"createSuccess": "Task created successfully",
209-
"errorWithDetail": "{message}: {detail}",
209+
"errorWithDetail": "{{message}}: {{detail}}",
210210
"jsonObjectRequired": "Must be a JSON object",
211211
"jsonObjectInvalid": "Please enter a valid JSON object",
212212
"jsonFormatError": "Invalid JSON format",
213-
"jsonFormatErrorWithMessage": "Invalid JSON format: {message}"
213+
"jsonFormatErrorWithMessage": "Invalid JSON format: {{message}}"
214214
},
215215
"placeholders": {
216216
"enter": "Please enter",
217217
"select": "Please select",
218-
"enterWithLabel": "Please enter {label}",
219-
"selectWithLabel": "Please select {label}"
218+
"enterWithLabel": "Please enter {{label}}",
219+
"selectWithLabel": "Please select {{label}}"
220220
}
221221
},
222222
"scheduler": {
@@ -356,7 +356,7 @@
356356
"deleteDatasetTitle": "Confirm delete this dataset?",
357357
"deleteDatasetDesc": "This dataset cannot be recovered after deletion. Proceed with caution.",
358358
"deleteFolderTitle": "Confirm delete folder?",
359-
"deleteFolderDesc": "Deleting folder \"{name}\" will remove all files and subfolders. This action cannot be undone.",
359+
"deleteFolderDesc": "Deleting folder \"{{name}}\" will remove all files and subfolders. This action cannot be undone.",
360360
"deleteConfirm": "Delete",
361361
"deleteCancel": "Cancel"
362362
},
@@ -368,14 +368,14 @@
368368
"tabQuality": "Data Quality",
369369
"sectionBasicInfo": "Basic Information",
370370
"sectionFileList": "File List",
371-
"selectedFiles": "Selected {count} files",
371+
"selectedFiles": "Selected {{count}} files",
372372
"goUp": "Go up",
373-
"currentPath": "Current path: {path}",
374-
"totalItems": "Total {total} items",
375-
"previewTitle": "File Preview: {name}",
373+
"currentPath": "Current path: {{path}}",
374+
"totalItems": "Total {{total}} items",
375+
"previewTitle": "File Preview: {{name}}",
376376
"previewEmpty": "No preview available or unsupported file type.",
377377
"previewInfoTitle": "File Info",
378-
"editTitle": "Edit Dataset - {name}"
378+
"editTitle": "Edit Dataset - {{name}}"
379379
},
380380
"labels": {
381381
"id": "ID",
@@ -409,7 +409,7 @@
409409
},
410410
"lineage": {
411411
"title": "Data Lineage",
412-
"stats": "{nodes} nodes · {edges} edges",
412+
"stats": "{{nodes}} nodes · {{edges}} edges",
413413
"legendDatasource": "Data Source",
414414
"legendDataset": "Dataset",
415415
"legendModel": "Model",
@@ -422,6 +422,7 @@
422422
"edgeTypeSynthesis": "Data Synthesis",
423423
"edgeTypeRatio": "Data Ratio",
424424
"edgeTypeDefault": "Processing Flow",
425+
"edgeTypeDefaultLabel": "Processing Flow",
425426
"detailBasicInfo": "Basic Information",
426427
"detailId": "ID:",
427428
"detailName": "Name:",
@@ -436,13 +437,21 @@
436437
"detailNoDownstream": "No downstream impacts",
437438
"processDetail": "Process Detail",
438439
"processId": "Process ID:",
440+
"relationships": "Upstream and Downstream",
439441
"processUpstream": "Upstream:",
440442
"processDownstream": "Downstream:",
443+
"processDescription": "Description",
444+
"processEmpty": "No process description",
441445
"nodeTypeDatasource": "Data Source",
442446
"nodeTypeDataset": "Dataset",
443447
"nodeTypeModel": "Model",
444448
"nodeTypeKnowledge": "Knowledge Base",
445-
"filesCount": "{count} files"
449+
"filesCount": "{{count}} files · {{size}}",
450+
"statusRunning": "Running",
451+
"statusStopped": "Stopped",
452+
"statusActive": "Active",
453+
"statusInactive": "Inactive",
454+
"statusDraft": "Draft"
446455
},
447456
"quality": {
448457
"titleDistribution": "Quality Distribution",
@@ -461,8 +470,8 @@
461470
"metricColumnIntegrity": "Column Integrity",
462471
"metricDuplicateRate": "Duplicate Rate",
463472
"recommendationTitle": "Quality Improvement Suggestions",
464-
"recommendationReviewLowQuality": "Review or recollect {count} low-quality samples",
465-
"recommendationSupplementMetadata": "Check and supplement missing metadata fields (missing: {missing})",
473+
"recommendationReviewLowQuality": "Review or recollect {{count}} low-quality samples",
474+
"recommendationSupplementMetadata": "Check and supplement missing metadata fields (missing: {{missing}})",
466475
"recommendationBalanceDistribution": "Consider adding more underrepresented samples to balance distribution",
467476
"imageClarity": "Image Clarity",
468477
"colorConsistency": "Color Consistency",
@@ -476,7 +485,21 @@
476485
"fileIntegrity": "File Integrity",
477486
"fieldIntegrity": "Field Integrity",
478487
"columnIntegrity": "Column Integrity",
479-
"duplicateRate": "Duplicate Rate"
488+
"duplicateRate": "Duplicate Rate",
489+
"labelDistribution": {
490+
"title": "Label Distribution Details",
491+
"category": "Category",
492+
"labelName": "Label Name",
493+
"count": "Count",
494+
"percentage": "Percentage",
495+
"noData": "No label distribution data",
496+
"noDataSubtitle": "No label distribution data available",
497+
"statisticsTitle": "Dataset Label Statistics",
498+
"statisticsSummary": "{{categoryCount}} categories, {{totalLabels}} label samples",
499+
"detailsCardTitle": "Label Distribution Details",
500+
"totalLabels": "Total: {{count}} labels",
501+
"moreLabels": "And {{count}} more labels..."
502+
}
480503
},
481504
"import": {
482505
"title": "Import Data",
@@ -486,7 +509,7 @@
486509
"uploadFolderHint": "Drag folder here or click to select folder",
487510
"fileLabel": "File:",
488511
"folderLabel": "Folder:",
489-
"warningTypeMismatch": "Dataset type is {type}. Some selected files may not match; please confirm.",
512+
"warningTypeMismatch": "Dataset type is {{type}}. Some selected files may not match; please confirm.",
490513
"warningUseFolderUpload": "To upload a folder, use the \"Local Folder Upload\" area on the right.",
491514
"warningUseFileUpload": "To upload a single file, use the \"Local File Upload\" area on the left.",
492515
"obsEndpoint": "Endpoint",
@@ -553,7 +576,7 @@
553576
"collection": "Collection Task Import"
554577
}
555578
},
556-
"common": {
579+
"common": {
557580
"actions": {
558581
"createTask": "Create Task"
559582
},
@@ -570,5 +593,27 @@
570593
"pending": "Ready"
571594
}
572595
}
596+
},
597+
"tagManagement": {
598+
"manageTags": "Manage Tags",
599+
"addTag": "Add Tag",
600+
"tagName": "Tag Name",
601+
"tagNamePlaceholder": "Enter tag name...",
602+
"createTag": "Create",
603+
"selectExistingTags": "Select existing tags",
604+
"createNewTag": "Create new tag",
605+
"newTagNamePlaceholder": "Enter new tag name...",
606+
"noAvailableTags": "No available tags. Please create a tag first.",
607+
"cancel": "Cancel",
608+
"messages": {
609+
"fetchFailed": "Failed to fetch tags",
610+
"addSuccess": "Tag added successfully",
611+
"addFailed": "Failed to add tag",
612+
"deleteSuccess": "Tag deleted successfully",
613+
"deleteFailed": "Failed to delete tag",
614+
"updateSuccess": "Tag updated successfully",
615+
"updateFailed": "Failed to update tag"
616+
},
617+
"uncategorized": "Uncategorized"
573618
}
574619
}

0 commit comments

Comments
 (0)