From af8865327a534a62efd8f9bfbe8b48e27792edd5 Mon Sep 17 00:00:00 2001
From: HUi <32211782+huynguyeexn@users.noreply.github.com>
Date: Sat, 20 Dec 2025 02:17:34 +0700
Subject: [PATCH] feat: Add Vietnamese translation (#1459)
---
client/src/locales/index.js | 2 +
client/src/locales/vi-VN/core.js | 501 ++++++++++++++++++
client/src/locales/vi-VN/index.js | 8 +
client/src/locales/vi-VN/login.js | 34 ++
client/src/locales/vi-VN/markdown-editor.json | 169 ++++++
.../controllers/access-tokens/accept-terms.js | 2 +-
server/api/controllers/users/create.js | 2 +-
server/api/controllers/users/update.js | 2 +-
server/api/models/User.js | 3 +-
server/config/i18n.js | 1 +
server/config/locales/vi-VN.json | 19 +
11 files changed, 739 insertions(+), 4 deletions(-)
create mode 100644 client/src/locales/vi-VN/core.js
create mode 100644 client/src/locales/vi-VN/index.js
create mode 100644 client/src/locales/vi-VN/login.js
create mode 100644 client/src/locales/vi-VN/markdown-editor.json
create mode 100644 server/config/locales/vi-VN.json
diff --git a/client/src/locales/index.js b/client/src/locales/index.js
index 19c4a50f..8cec4da8 100644
--- a/client/src/locales/index.js
+++ b/client/src/locales/index.js
@@ -37,6 +37,7 @@ import svSE from './sv-SE';
import trTR from './tr-TR';
import ukUA from './uk-UA';
import uzUZ from './uz-UZ';
+import viVN from './vi-VN';
import zhCN from './zh-CN';
import zhTW from './zh-TW';
@@ -73,6 +74,7 @@ const locales = [
trTR,
ukUA,
uzUZ,
+ viVN,
zhCN,
zhTW,
];
diff --git a/client/src/locales/vi-VN/core.js b/client/src/locales/vi-VN/core.js
new file mode 100644
index 00000000..4911cd58
--- /dev/null
+++ b/client/src/locales/vi-VN/core.js
@@ -0,0 +1,501 @@
+import dateFns from 'date-fns/locale/vi';
+import timeAgo from 'javascript-time-ago/locale/vi';
+
+import markdownEditor from './markdown-editor.json';
+
+export default {
+ dateFns,
+ timeAgo,
+ markdownEditor,
+
+ format: {
+ date: 'dd/MM/yyyy',
+ time: 'HH:mm',
+ dateTime: '$t(format:date) $t(format:time)',
+ longDate: 'd MMM',
+ longDateTime: "d MMMM 'lúc' HH:mm",
+ fullDate: 'd MMM, y',
+ fullDateTime: "d MMMM, y 'lúc' HH:mm",
+ },
+
+ translation: {
+ common: {
+ aboutApp_title: 'Về ứng dụng',
+ aboutPlanka_title: 'Về PLANKA',
+ accessToken: 'Access token',
+ account: 'Tài khoản',
+ actions: 'Thao tác',
+ activateUser_title: 'Kích hoạt người dùng',
+ active: 'Đang hoạt động',
+ addAttachment_title: 'Thêm tệp đính kèm',
+ addCustomFieldGroup_title: 'Thêm nhóm trường tùy chỉnh',
+ addCustomField_title: 'Thêm trường tùy chỉnh',
+ addManager_title: 'Thêm quản lý',
+ addMember_title: 'Thêm thành viên',
+ addTaskList_title: 'Thêm danh sách công việc',
+ addUser_title: 'Thêm người dùng',
+ admin: 'Quản trị viên',
+ administration: 'Quản trị hệ thống',
+ all: 'Tất cả',
+ allChangesWillBeAutomaticallySavedAfterConnectionRestored:
+ 'Mọi thay đổi sẽ tự động được lưu
sau khi kết nối được khôi phục.',
+ alphabetically: 'Theo bảng chữ cái',
+ alwaysDisplayCardCreator: 'Luôn hiển thị trình tạo thẻ',
+ apiKeyCreated_title: 'Đã tạo API Key',
+ apiKey_title: 'API Key',
+ archive: 'Lưu trữ',
+ archiveCard_title: 'Lưu trữ thẻ',
+ archiveCards_title: 'Lưu trữ các thẻ',
+ areYouSureYouWantToActivateThisUser: 'Bạn có chắc chắn muốn kích hoạt người dùng này không?',
+ areYouSureYouWantToArchiveCards: 'Bạn có chắc chắn muốn lưu trữ các thẻ này không?',
+ areYouSureYouWantToArchiveThisCard: 'Bạn có chắc chắn muốn lưu trữ thẻ này không?',
+ areYouSureYouWantToAssignThisProjectManagerAsOwner:
+ 'Bạn có chắc chắn muốn chỉ định quản lý dự án này làm chủ sở hữu không?',
+ areYouSureYouWantToDeactivateThisUser:
+ 'Bạn có chắc chắn muốn hủy kích hoạt người dùng này không?',
+ areYouSureYouWantToDeleteThisApiKey: 'Bạn có chắc chắn muốn xóa API Key này không?',
+ areYouSureYouWantToDeleteThisAttachment: 'Bạn có chắc chắn muốn xóa tệp đính kèm này không?',
+ areYouSureYouWantToDeleteThisBackgroundImage: 'Bạn có chắc chắn muốn xóa ảnh nền này không?',
+ areYouSureYouWantToDeleteThisBoard: 'Bạn có chắc chắn muốn xóa bảng này không?',
+ areYouSureYouWantToDeleteThisCard: 'Bạn có chắc chắn muốn xóa thẻ này không?',
+ areYouSureYouWantToDeleteThisCardForever:
+ 'Bạn có chắc chắn muốn xóa vĩnh viễn thẻ này không?',
+ areYouSureYouWantToDeleteThisComment: 'Bạn có chắc chắn muốn xóa bình luận này không?',
+ areYouSureYouWantToDeleteThisCustomField:
+ 'Bạn có chắc chắn muốn xóa trường tùy chỉnh này không?',
+ areYouSureYouWantToDeleteThisCustomFieldGroup:
+ 'Bạn có chắc chắn muốn xóa nhóm trường tùy chỉnh này không?',
+ areYouSureYouWantToDeleteThisLabel: 'Bạn có chắc chắn muốn xóa nhãn này không?',
+ areYouSureYouWantToDeleteThisList:
+ 'Bạn có chắc chắn muốn xóa danh sách này? Tất cả các thẻ sẽ được chuyển vào thùng rác.',
+ areYouSureYouWantToDeleteThisNotificationService:
+ 'Bạn có chắc chắn muốn xóa dịch vụ thông báo này không?',
+ areYouSureYouWantToDeleteThisProject: 'Bạn có chắc chắn muốn xóa dự án này không?',
+ areYouSureYouWantToDeleteThisTask: 'Bạn có chắc chắn muốn xóa nhiệm vụ này không?',
+ areYouSureYouWantToDeleteThisTaskList:
+ 'Bạn có chắc chắn muốn xóa danh sách công việc này không?',
+ areYouSureYouWantToDeleteThisUser: 'Bạn có chắc chắn muốn xóa người dùng này không?',
+ areYouSureYouWantToDeleteThisWebhook: 'Bạn có chắc chắn muốn xóa webhook này không?',
+ areYouSureYouWantToEmptyTrash: 'Bạn có chắc chắn muốn dọn sạch thùng rác không?',
+ areYouSureYouWantToLeaveBoard: 'Bạn có chắc chắn muốn rời khỏi bảng này không?',
+ areYouSureYouWantToLeaveProject: 'Bạn có chắc chắn muốn rời khỏi dự án này không?',
+ areYouSureYouWantToMakeThisProjectPrivate:
+ 'Bạn có chắc chắn muốn chuyển dự án này sang riêng tư không?',
+ areYouSureYouWantToMakeThisProjectShared:
+ 'Bạn có chắc chắn muốn chuyển dự án này sang công khai không?',
+ areYouSureYouWantToRegenerateThisApiKey:
+ 'Bạn có chắc chắn muốn tạo lại API Key này không? Key cũ sẽ không còn hiệu lực.',
+ areYouSureYouWantToRemoveThisManagerFromProject:
+ 'Bạn có chắc chắn muốn xóa quản lý này khỏi dự án không?',
+ areYouSureYouWantToRemoveThisMemberFromBoard:
+ 'Bạn có chắc chắn muốn xóa thành viên này khỏi bảng không?',
+ assignAsOwner_title: 'Chỉ định làm chủ sở hữu',
+ atLeastOneListMustBePresent: 'Phải có ít nhất một danh sách',
+ attachment: 'Tệp đính kèm',
+ attachments: 'Các tệp đính kèm',
+ authentication: 'Xác thực',
+ background: 'Nền',
+ baseCustomFields_title: 'Các trường tùy chỉnh cơ sở',
+ baseGroup: 'Nhóm cơ sở',
+ board: 'Bảng',
+ boardActions_title: 'Thao tác với bảng',
+ boardNotFound_title: 'Không tìm thấy bảng',
+ boardSubscribed: 'Đã đăng ký theo dõi bảng',
+ boardUser: 'Người dùng bảng',
+ byCreationTime: 'Theo thời gian tạo',
+ byDefault: 'Theo mặc định',
+ byDueDate: 'Theo hạn chót',
+ canBeInvitedToWorkInBoards: 'Có thể được mời làm việc trong các bảng.',
+ canComment: 'Có thể bình luận',
+ canCreateOwnProjectsAndBeInvitedToWorkInOthers:
+ 'Có thể tạo dự án riêng và được mời làm việc trong các dự án khác.',
+ canEditBoardLayoutAndAssignMembersToCards:
+ 'Có thể chỉnh sửa bố cục bảng và chỉ định thành viên cho các thẻ.',
+ canManageSystemWideSettingsAndActAsProjectOwner:
+ 'Có thể quản lý các thiết lập hệ thống và đóng vai trò là chủ sở hữu dự án.',
+ canOnlyViewBoard: 'Chỉ có thể xem bảng.',
+ cardActions_title: 'Thao tác với thẻ',
+ cardNotFound_title: 'Không tìm thấy thẻ',
+ cardsOnThisListAreAvailableToAllBoardMembers:
+ 'Các thẻ trong danh sách này khả dụng cho tất cả thành viên trong bảng.',
+ cardsOnThisListAreCompleteAndReadyToBeArchived:
+ 'Các thẻ trong danh sách này đã hoàn thành và sẵn sàng để lưu trữ.',
+ cardsOnThisListAreReadyToBeWorkedOn: 'Các thẻ trong danh sách này đã sẵn sàng để thực hiện.',
+ clickHereOrRefreshPageToUpdate: '<0>Nhấp vào đây0> hoặc tải lại trang để cập nhật.',
+ clientHostnameInEhlo: 'Tên máy chủ của máy khách (EHLO)',
+ closed: 'Đã đóng',
+ color: 'Màu sắc',
+ comments: 'Bình luận',
+ contentExceedsLimit: 'Nội dung vượt quá giới hạn {{limit}}',
+ contentOfThisAttachmentIsTooBigToDisplay:
+ 'Nội dung của tệp đính kèm này quá lớn để hiển thị.',
+ copy_inline: 'sao chép',
+ createBoard_title: 'Tạo bảng',
+ createCustomFieldGroup_title: 'Tạo nhóm trường tùy chỉnh',
+ createLabel_title: 'Tạo nhãn',
+ createNewOneOrSelectExistingOne: 'Tạo cái mới hoặc chọn
cái đã có.',
+ createProject_title: 'Tạo dự án',
+ createTextFile_title: 'Tạo tệp văn bản',
+ creator: 'Người tạo',
+ currentPassword: 'Mật khẩu hiện tại',
+ currentUser: 'Người dùng hiện tại',
+ customFieldGroup_title: 'Nhóm trường tùy chỉnh',
+ customFieldGroups_title: 'Các nhóm trường tùy chỉnh',
+ customField_title: 'Trường tùy chỉnh',
+ customFields_title: 'Các trường tùy chỉnh',
+ customerPanel_title: 'Bảng điều khiển khách hàng',
+ dangerZone_title: 'Khu vực nguy hiểm',
+ date: 'Ngày',
+ deactivateUser_title: 'Hủy kích hoạt người dùng',
+ defaultCardType_title: 'Loại thẻ mặc định',
+ defaultFrom: 'Người gửi mặc định ("from")',
+ defaultView_title: 'Chế độ xem mặc định',
+ deleteAllBoardsToBeAbleToDeleteThisProject: 'Xóa tất cả các bảng để có thể xóa dự án này',
+ deleteApiKey_title: 'Xóa API Key',
+ deleteAttachment_title: 'Xóa tệp đính kèm',
+ deleteBackgroundImage_title: 'Xóa ảnh nền',
+ deleteBoard_title: 'Xóa bảng',
+ deleteCardForever_title: 'Xóa thẻ vĩnh viễn',
+ deleteCard_title: 'Xóa thẻ',
+ deleteComment_title: 'Xóa bình luận',
+ deleteCustomFieldGroup_title: 'Xóa nhóm trường tùy chỉnh',
+ deleteCustomField_title: 'Xóa trường tùy chỉnh',
+ deleteLabel_title: 'Xóa nhãn',
+ deleteList_title: 'Xóa danh sách',
+ deleteNotificationService_title: 'Xóa dịch vụ thông báo',
+ deleteProject_title: 'Xóa dự án',
+ deleteTaskList_title: 'Xóa danh sách công việc',
+ deleteTask_title: 'Xóa nhiệm vụ',
+ deleteUser_title: 'Xóa người dùng',
+ deleteWebhook_title: 'Xóa webhook',
+ deletedUser_title: 'Người dùng đã bị xóa',
+ description: 'Mô tả',
+ display: 'Hiển thị',
+ dropFileToUpload: 'Thả tệp vào đây để tải lên',
+ dueDate_title: 'Hạn chót',
+ dynamicAndUnevenlySpacedLayout: 'Bố cục động và khoảng cách không đều.',
+ editAttachment_title: 'Chỉnh sửa tệp đính kèm',
+ editAvatar_title: 'Chỉnh sửa ảnh đại diện',
+ editColor_title: 'Chỉnh sửa màu sắc',
+ editCustomFieldGroup_title: 'Chỉnh sửa nhóm trường tùy chỉnh',
+ editCustomField_title: 'Chỉnh sửa trường tùy chỉnh',
+ editDueDate_title: 'Chỉnh sửa hạn chót',
+ editEmail_title: 'Chỉnh sửa E-mail',
+ editInformation_title: 'Chỉnh sửa thông tin',
+ editLabel_title: 'Chỉnh sửa nhãn',
+ editPassword_title: 'Chỉnh sửa mật khẩu',
+ editPermissions_title: 'Chỉnh sửa quyền hạn',
+ editRole_title: 'Chỉnh sửa vai trò',
+ editStopwatch_title: 'Chỉnh sửa đồng hồ bấm giờ',
+ editType_title: 'Chỉnh sửa loại',
+ editUsername_title: 'Chỉnh sửa tên người dùng',
+ editor: 'Trình chỉnh sửa',
+ editors: 'Những người chỉnh sửa',
+ email: 'E-mail',
+ emptyTrash_title: 'Dọn sạch thùng rác',
+ enterCardTitle: 'Nhập tiêu đề thẻ...',
+ enterDescription: 'Nhập mô tả...',
+ enterFilename: 'Nhập tên tệp',
+ enterListTitle: 'Nhập tiêu đề danh sách...',
+ enterTaskDescription: 'Nhập mô tả nhiệm vụ...',
+ events: 'Sự kiện',
+ excludedEvents: 'Các sự kiện loại trừ',
+ expandTaskListsByDefault: 'Mặc định mở rộng danh sách nhiệm vụ',
+ filterByLabels_title: 'Lọc theo nhãn',
+ filterByMembers_title: 'Lọc theo thành viên',
+ forPersonalProjects: 'Dành cho các dự án cá nhân.',
+ forTeamBasedProjects: 'Dành cho các dự án nhóm.',
+ fromComputer_title: 'Từ máy tính',
+ fromTrello: 'Từ Trello',
+ fullKeyIsHiddenForSecurityReasons:
+ 'Mã đầy đủ bị ẩn vì lý do bảo mật. Hãy tạo lại để có mã mới.',
+ general: 'Chung',
+ gradients: 'Màu gradient',
+ grid: 'Lưới',
+ hideCompletedTasks: 'Ẩn các nhiệm vụ đã hoàn thành',
+ hideFromProjectListAndFavorites: 'Ẩn khỏi danh sách dự án và mục yêu thích',
+ host: 'Máy chủ (Host)',
+ hours: 'Giờ',
+ identity: 'Danh tính',
+ importBoard_title: 'Nhập bảng',
+ information: 'Thông tin',
+ invalidCurrentPassword: 'Mật khẩu hiện tại không hợp lệ',
+ kanban: 'Kanban',
+ labels: 'Nhãn',
+ language: 'Ngôn ngữ',
+ leaveBoard_title: 'Rời khỏi bảng',
+ leaveProject_title: 'Rời khỏi dự án',
+ limitCardTypesToDefaultOne: 'Giới hạn các loại thẻ về loại mặc định',
+ linkToCard: 'Liên kết tới thẻ',
+ list: 'Danh sách',
+ listActions_title: 'Thao tác với danh sách',
+ lists: 'Danh sách',
+ makeProjectPrivate_title: 'Chuyển dự án sang riêng tư',
+ makeProjectShared_title: 'Chuyển dự án sang công khai',
+ managers: 'Quản lý',
+ memberActions_title: 'Thao tác với thành viên',
+ members: 'Thành viên',
+ minutes: 'Phút',
+ moreActions: 'Thêm thao tác',
+ moreActions_title: 'Thêm thao tác',
+ moveCard_title: 'Di chuyển thẻ',
+ moveList_title: 'Di chuyển danh sách',
+ myOwn_title: 'Của tôi',
+ name: 'Tên',
+ newEmail: 'E-mail mới',
+ newPassword: 'Mật khẩu mới',
+ newUsername: 'Tên người dùng mới',
+ newVersionAvailable: 'Có phiên bản mới',
+ newestFirst: 'Mới nhất trước',
+ noApiKeyCreated: 'Chưa có API Key nào được tạo.',
+ noBoards: 'Không có bảng nào',
+ noCardsFound: 'Không tìm thấy thẻ nào.',
+ noConnectionToServer: 'Không có kết nối tới máy chủ',
+ noLists: 'Không có danh sách nào',
+ noProjects: 'Không có dự án nào',
+ noUnreadNotifications: 'Không có thông báo chưa đọc.',
+ notifications: 'Thông báo',
+ oldestFirst: 'Cũ nhất trước',
+ onlyOneManagerShouldRemainToMakeThisProjectPrivate:
+ 'Chỉ được để lại một quản lý để chuyển dự án này sang riêng tư',
+ openBoard_title: 'Mở bảng',
+ optional_inline: 'tùy chọn',
+ organization: 'Tổ chức',
+ others: 'Khác',
+ passwordIsSet: 'Mật khẩu đã được thiết lập',
+ phone: 'Điện thoại',
+ plankaUsesAppriseToSendNotificationsToOver100PopularServices:
+ 'PLANKA sử dụng <1><0>Apprise0>1> để gửi thông báo tới hơn 100 dịch vụ phổ biến.',
+ port: 'Cổng',
+ preferences: 'Tùy chọn',
+ pressPasteShortcutToAddAttachmentFromClipboard:
+ 'Mẹo: nhấn Ctrl-V (Cmd-V trên Mac) để thêm tệp đính kèm từ khay nhớ tạm.',
+ private: 'Riêng tư',
+ project: 'Dự án',
+ projectNotFound_title: 'Không tìm thấy dự án',
+ projectOwner: 'Chủ sở hữu dự án',
+ referenceDataAndKnowledgeStorage: 'Lưu trữ dữ liệu tham khảo và kiến thức.',
+ regenerateApiKey_title: 'Tạo lại API Key',
+ rejectUnauthorizedTlsCertificates: 'Từ chối chứng chỉ TLS không được xác thực',
+ removeManager_title: 'Xóa quản lý',
+ removeMember_title: 'Xóa thành viên',
+ role: 'Vai trò',
+ saveThisKeyItWillNotBeShownAgain: 'Lưu mã này — nó sẽ không được hiển thị lại!',
+ searchCards: 'Tìm kiếm thẻ...',
+ searchCustomFieldGroups: 'Tìm kiếm nhóm trường tùy chỉnh...',
+ searchCustomFields: 'Tìm kiếm trường tùy chỉnh...',
+ searchLabels: 'Tìm kiếm nhãn...',
+ searchLists: 'Tìm kiếm danh sách...',
+ searchMembers: 'Tìm kiếm thành viên...',
+ searchProjects: 'Tìm kiếm dự án...',
+ searchUsers: 'Tìm kiếm người dùng...',
+ seconds: 'Giây',
+ selectAssignee_title: 'Chọn người thực hiện',
+ selectBoard: 'Chọn bảng',
+ selectList: 'Chọn danh sách',
+ selectListToRestoreThisCard: 'Chọn danh sách để khôi phục thẻ này',
+ selectOrder_title: 'Chọn thứ tự',
+ selectPermissions_title: 'Chọn quyền hạn',
+ selectProject: 'Chọn dự án',
+ selectRole_title: 'Chọn vai trò',
+ selectType_title: 'Chọn loại',
+ sequentialDisplayOfCards: 'Hiển thị các thẻ theo trình tự.',
+ settings: 'Cài đặt',
+ shared: 'Đã chia sẻ',
+ sharedWithMe_title: 'Được chia sẻ với tôi',
+ showOnFrontOfCard: 'Hiển thị trên mặt trước của thẻ',
+ smtp: 'SMTP',
+ sortList_title: 'Sắp xếp danh sách',
+ sourceCardIsNoLongerAvailableForCopying: 'Thẻ nguồn không còn khả dụng để sao chép.',
+ sourceCardIsNoLongerAvailableForMoving: 'Thẻ nguồn không còn khả dụng để di chuyển.',
+ stopwatch: 'Đồng hồ bấm giờ',
+ story: 'Câu chuyện',
+ subscribeToCardWhenCommenting: 'Đăng ký theo dõi thẻ khi bình luận',
+ subscribeToMyOwnCardsByDefault: 'Mặc định đăng ký theo dõi các thẻ của tôi',
+ taskActions_title: 'Thao tác với nhiệm vụ',
+ taskAssignmentAndProjectCompletion: 'Phân công nhiệm vụ và hoàn thành dự án.',
+ taskListActions_title: 'Thao tác với danh sách nhiệm vụ',
+ taskList_title: 'Danh sách nhiệm vụ',
+ team: 'Nhóm',
+ termsOfService_title: 'Điều khoản dịch vụ',
+ testLog_title: 'Test log',
+ thereIsNoPreviewAvailableForThisAttachment: 'Không có bản xem trước cho tệp đính kèm này.',
+ time: 'Thời gian',
+ title: 'Tiêu đề',
+ trash: 'Thùng rác',
+ trashHasBeenSuccessfullyEmptied: 'Thùng rác đã được dọn sạch thành công.',
+ turnOffRecentCardHighlighting: 'Tắt làm nổi bật thẻ gần đây',
+ typeNameToConfirm: 'Nhập tên để xác nhận.',
+ typeTitleToConfirm: 'Nhập tiêu đề để xác nhận.',
+ unsavedChanges: 'Thay đổi chưa được lưu',
+ uploadFailedFileIsTooBig: 'Tải lên thất bại: Tệp quá lớn.',
+ uploadFailedNotEnoughStorageSpace: 'Tải lên thất bại: Không đủ không gian lưu trữ.',
+ uploadedImages: 'Ảnh đã tải lên',
+ url: 'URL',
+ useSecureConnection: 'Sử dụng kết nối bảo mật',
+ userActions_title: 'Thao tác với người dùng',
+ userAddedCardToList: '<0>{{user}}0> đã thêm <2>{{card}}2> vào {{list}}',
+ userAddedThisCardToList: '<0>{{user}}0> đã thêm thẻ này vào {{list}}',
+ userAddedUserToCard: '<0>{{actorUser}}0> đã thêm {{addedUser}} vào <4>{{card}}4>',
+ userAddedUserToThisCard: '<0>{{actorUser}}0> đã thêm {{addedUser}} vào thẻ này',
+ userAddedYouToCard: '<0>{{user}}0> đã thêm bạn vào <2>{{card}}2>',
+ userCompletedTaskOnCard: '<0>{{user}}0> đã hoàn thành {{task}} trên <4>{{card}}4>',
+ userCompletedTaskOnThisCard: '<0>{{user}}0> đã hoàn thành {{task}} trên thẻ này',
+ userJoinedCard: '<0>{{user}}0> đã tham gia <2>{{card}}2>',
+ userJoinedThisCard: '<0>{{user}}0> đã tham gia thẻ này',
+ userLeftCard: '<0>{{user}}0> đã rời khỏi <2>{{card}}2>',
+ userLeftNewCommentToCard:
+ '<0>{{user}}0> đã để lại bình luận mới «{{comment}}» tại <2>{{card}}2>',
+ userLeftThisCard: '<0>{{user}}0> đã rời khỏi thẻ này',
+ userMarkedTaskIncompleteOnCard:
+ '<0>{{user}}0> đã đánh dấu {{task}} chưa hoàn thành trên <4>{{card}}4>',
+ userMarkedTaskIncompleteOnThisCard:
+ '<0>{{user}}0> đã đánh dấu {{task}} chưa hoàn thành trên thẻ này',
+ userMentionedYouInCommentOnCard:
+ '<0>{{user}}0> đã nhắc đến bạn trong một bình luận «{{comment}}» tại <2>{{card}}2>',
+ userMovedCardFromListToList:
+ '<0>{{user}}0> đã di chuyển <2>{{card}}2> từ {{fromList}} sang {{toList}}',
+ userMovedThisCardFromListToList:
+ '<0>{{user}}0> đã di chuyển thẻ này từ {{fromList}} sang {{toList}}',
+ userRemovedUserFromCard: '<0>{{actorUser}}0> đã xóa {{removedUser}} khỏi <4>{{card}}4>',
+ userRemovedUserFromThisCard: '<0>{{actorUser}}0> đã xóa {{removedUser}} khỏi thẻ này',
+ username: 'Tên đăng nhập',
+ users: 'Người dùng',
+ viewer: 'Người xem',
+ viewers: 'Người xem',
+ visualTaskManagementWithLists: 'Quản lý nhiệm vụ trực quan bằng danh sách.',
+ webhooks: 'Webhooks',
+ whatsNew_title: 'Có gì mới',
+ withoutBaseGroup: 'Không kèm nhóm cơ sở',
+ writeComment: 'Viết bình luận...',
+ },
+
+ action: {
+ activateUser: 'Kích hoạt người dùng',
+ activateUser_title: 'Kích hoạt Người dùng',
+ addAnotherCard: 'Thêm thẻ khác',
+ addAnotherList: 'Thêm danh sách khác',
+ addAnotherTask: 'Thêm nhiệm vụ khác',
+ addCard: 'Thêm thẻ',
+ addCard_title: 'Thêm Thẻ',
+ addComment: 'Thêm bình luận',
+ addCustomField: 'Thêm trường tùy chỉnh',
+ addCustomFieldGroup: 'Thêm nhóm trường tùy chỉnh',
+ addList: 'Thêm danh sách',
+ addMember: 'Thêm thành viên',
+ addMoreDetailedDescription: 'Thêm mô tả chi tiết hơn',
+ addTask: 'Thêm nhiệm vụ',
+ addTaskList: 'Thêm danh sách nhiệm vụ',
+ addToCard: 'Thêm vào thẻ',
+ addUser: 'Thêm người dùng',
+ addWebhook: 'Thêm webhook',
+ archive: 'Lưu trữ',
+ archiveCard: 'Lưu trữ thẻ',
+ archiveCard_title: 'Lưu trữ Thẻ',
+ archiveCards: 'Lưu trữ các thẻ',
+ archiveCards_title: 'Lưu trữ Các thẻ',
+ assignAsOwner: 'Chỉ định làm chủ sở hữu',
+ cancel: 'Hủy',
+ copy: 'Sao chép',
+ copyCard_title: 'Sao chép Thẻ',
+ createApiKey: 'Tạo API Key',
+ createBoard: 'Tạo bảng',
+ createCustomFieldGroup: 'Tạo nhóm trường tùy chỉnh',
+ createFile: 'Tạo tệp',
+ createLabel: 'Tạo nhãn',
+ createNewLabel: 'Tạo nhãn mới',
+ createProject: 'Tạo dự án',
+ cut: 'Cắt',
+ cutCard_title: 'Cắt Thẻ',
+ deactivateUser: 'Hủy kích hoạt người dùng',
+ deactivateUser_title: 'Hủy kích hoạt Người dùng',
+ delete: 'Xóa',
+ deleteApiKey: 'Xóa API Key',
+ deleteAttachment: 'Xóa tệp đính kèm',
+ deleteAvatar: 'Xóa ảnh đại diện',
+ deleteBackgroundImage: 'Xóa ảnh nền',
+ deleteBoard: 'Xóa bảng',
+ deleteBoard_title: 'Xóa Bảng',
+ deleteCard: 'Xóa thẻ',
+ deleteCardForever: 'Xóa thẻ vĩnh viễn',
+ deleteCard_title: 'Xóa Thẻ',
+ deleteComment: 'Xóa bình luận',
+ deleteCustomField: 'Xóa trường tùy chỉnh',
+ deleteCustomFieldGroup: 'Xóa nhóm trường tùy chỉnh',
+ deleteForever_title: 'Xóa Vĩnh viễn',
+ deleteGroup: 'Xóa nhóm',
+ deleteLabel: 'Xóa nhãn',
+ deleteList: 'Xóa danh sách',
+ deleteList_title: 'Xóa Danh sách',
+ deleteNotificationService: 'Xóa dịch vụ thông báo',
+ deleteProject: 'Xóa dự án',
+ deleteProject_title: 'Xóa Dự án',
+ deleteTask: 'Xóa nhiệm vụ',
+ deleteTaskList: 'Xóa danh sách nhiệm vụ',
+ deleteTask_title: 'Xóa Nhiệm vụ',
+ deleteUser: 'Xóa người dùng',
+ deleteUser_title: 'Xóa Người dùng',
+ deleteWebhook: 'Xóa webhook',
+ dismissAll: 'Bỏ qua tất cả',
+ download: 'Tải xuống',
+ duplicateCard_title: 'Nhân bản Thẻ',
+ edit: 'Chỉnh sửa',
+ editColor_title: 'Chỉnh sửa Màu sắc',
+ editDescription_title: 'Chỉnh sửa Mô tả',
+ editDueDate_title: 'Chỉnh sửa Hạn chót',
+ editEmail_title: 'Chỉnh sửa E-mail',
+ editGroup: 'Chỉnh sửa nhóm',
+ editInformation_title: 'Chỉnh sửa Thông tin',
+ editPassword_title: 'Chỉnh sửa Mật khẩu',
+ editPermissions: 'Chỉnh sửa quyền hạn',
+ editRole_title: 'Chỉnh sửa Vai trò',
+ editStopwatch_title: 'Chỉnh sửa Đồng hồ bấm giờ',
+ editTitle_title: 'Chỉnh sửa Tiêu đề',
+ editType_title: 'Chỉnh sửa Loại',
+ editUsername_title: 'Chỉnh sửa Tên người dùng',
+ emptyTrash: 'Dọn sạch thùng rác',
+ emptyTrash_title: 'Dọn sạch Thùng rác',
+ import: 'Nhập',
+ join: 'Tham gia',
+ leave: 'Rời khỏi',
+ leaveBoard: 'Rời khỏi bảng',
+ leaveProject: 'Rời khỏi dự án',
+ logOut_title: 'Đăng xuất',
+ makeCover_title: 'Đặt làm ảnh bìa',
+ makeProjectPrivate: 'Chuyển dự án sang riêng tư',
+ makeProjectPrivate_title: 'Chuyển Dự án sang Riêng tư',
+ makeProjectShared: 'Chuyển dự án sang công khai',
+ makeProjectShared_title: 'Chuyển Dự án sang Công khai',
+ move: 'Di chuyển',
+ moveCard_title: 'Di chuyển Thẻ',
+ moveList_title: 'Di chuyển Danh sách',
+ regenerateApiKey: 'Tạo lại API Key',
+ remove: 'Gỡ bỏ',
+ removeAssignee: 'Gỡ bỏ người thực hiện',
+ removeColor: 'Gỡ bỏ màu sắc',
+ removeCover_title: 'Gỡ bỏ ảnh bìa',
+ removeFromBoard: 'Gỡ bỏ khỏi bảng',
+ removeFromProject: 'Gỡ bỏ khỏi dự án',
+ removeManager: 'Gỡ bỏ quản lý',
+ removeMember: 'Gỡ bỏ thành viên',
+ restoreToList: 'Khôi phục về {{list}}',
+ returnToBoard: 'Quay lại bảng',
+ save: 'Lưu',
+ sendTestEmail: 'Gửi thử e-mail',
+ showActive: 'Hiển thị đang hoạt động',
+ showAllAttachments: 'Hiển thị tất cả tệp đính kèm ({{hidden}} bị ẩn)',
+ showCardsWithThisUser: 'Hiển thị các thẻ của người dùng này',
+ showDeactivated: 'Hiển thị đã hủy kích hoạt',
+ showFewerAttachments: 'Hiển thị ít tệp đính kèm hơn',
+ showLess: 'Ẩn bớt',
+ showMore: 'Xem thêm',
+ sortList_title: 'Sắp xếp Danh sách',
+ start: 'Bắt đầu',
+ stop: 'Dừng',
+ subscribe: 'Đăng ký theo dõi',
+ unsubscribe: 'Hủy đăng ký theo dõi',
+ uploadNewAvatar: 'Tải lên ảnh đại diện mới',
+ uploadNewImage: 'Tải lên ảnh mới',
+ },
+ },
+};
diff --git a/client/src/locales/vi-VN/index.js b/client/src/locales/vi-VN/index.js
new file mode 100644
index 00000000..a4d67526
--- /dev/null
+++ b/client/src/locales/vi-VN/index.js
@@ -0,0 +1,8 @@
+import login from './login';
+
+export default {
+ language: 'vi-VN',
+ country: 'vn',
+ name: 'Tiếng Việt',
+ embeddedLocale: login,
+};
diff --git a/client/src/locales/vi-VN/login.js b/client/src/locales/vi-VN/login.js
new file mode 100644
index 00000000..e4de4afc
--- /dev/null
+++ b/client/src/locales/vi-VN/login.js
@@ -0,0 +1,34 @@
+export default {
+ translation: {
+ common: {
+ activeUsersLimitReached: 'Đã đạt giới hạn người dùng hoạt động',
+ adminLoginRequiredToInitializeInstance: 'Cần đăng nhập quản trị để khởi tạo phiên bản',
+ emailAlreadyInUse: 'E-mail đã được sử dụng',
+ emailOrUsername: 'E-mail hoặc tên đăng nhập',
+ iHaveReadAndAgreeToTheseTerms: 'Tôi đã đọc và đồng ý với các điều khoản này',
+ invalidCredentials: 'Thông tin đăng nhập không hợp lệ',
+ invalidEmailOrUsername: 'E-mail hoặc tên đăng nhập không hợp lệ',
+ invalidPassword: 'Mật khẩu không hợp lệ',
+ logIn_title: 'Đăng nhập',
+ noInternetConnection: 'Không có kết nối Internet',
+ or: 'Hoặc',
+ pageNotFound_title: 'Không tìm thấy trang',
+ password: 'Mật khẩu',
+ poweredByPlanka: 'Được phát triển bởi <1>PLANKA1>',
+ serverConnectionFailed: 'Không kết nối được tới máy chủ',
+ unknownError: 'Lỗi không xác định, thử lại sau',
+ useSingleSignOn: 'Sử dụng đăng nhập một lần (SSO)',
+ usernameAlreadyInUse: 'Tên đăng nhập đã được sử dụng',
+ whoops_title: 'Ôi thôi chếcccc!',
+ },
+
+ action: {
+ cancelAndClose: 'Hủy và đóng',
+ continue: 'Tiếp tục',
+ goBack: 'Quay lại',
+ goHome: 'Về trang chủ',
+ logIn: 'Đăng nhập',
+ logInWithSso: 'Đăng nhập bằng SSO',
+ },
+ },
+};
diff --git a/client/src/locales/vi-VN/markdown-editor.json b/client/src/locales/vi-VN/markdown-editor.json
new file mode 100644
index 00000000..6072201a
--- /dev/null
+++ b/client/src/locales/vi-VN/markdown-editor.json
@@ -0,0 +1,169 @@
+{
+ "action-previews": {
+ "text": "Đây là văn bản không có tiêu đề.\nCả tiêu đề và nội dung\ncó thể được in đậm, in nghiêng, đổi màu,\ngạch ngang và gạch dưới.",
+ "text-with-head": "Đây là văn bản có tiêu đề.\nCả tiêu đề và nội dung\ncó thể được in đậm, in nghiêng, đổi màu,\ngạch ngang và gạch dưới.",
+ "heading": "Tiêu đề"
+ },
+ "bundle": {
+ "error-title": "Lỗi trong trình soạn thảo markdown",
+ "settings_wysiwyg": "Trình soạn thảo trực quan (WYSIWYG)",
+ "settings_markup": "Markdown",
+ "markup_placeholder": "Nhập markdown..."
+ },
+ "codeblock": {
+ "remove": "Xóa",
+ "empty_option": "Không tìm thấy kết quả",
+ "show_line_numbers": "Số dòng"
+ },
+ "common": {
+ "delete": "Xóa",
+ "edit": "Chỉnh sửa",
+ "toolbar_action_disabled": "Phần tử đánh dấu không tương thích"
+ },
+ "forms": {
+ "common_action_cancel": "Hủy",
+ "common_action_submit": "Gửi",
+ "common_action_upload": "Chọn",
+ "common_tab_attach": "Thêm từ thiết bị",
+ "common_tab_link": "Thêm theo liên kết",
+ "common_link": "Liên kết",
+ "common_sizes": "Kích thước, px",
+ "image_name": "Tiêu đề",
+ "image_link_href": "Liên kết ảnh",
+ "image_link_href_help": "Địa chỉ mà liên kết ảnh dẫn tới.",
+ "image_alt": "Văn bản thay thế (alt)",
+ "image_alt_help": "Văn bản thay thế hiển thị khi ảnh không thể tải.",
+ "image_upload_help": "Ảnh JPEG, GIF hoặc PNG không lớn hơn 1 MB.",
+ "image_upload_failed": "Thêm ảnh thất bại",
+ "image_size_width": "Chiều rộng",
+ "image_size_height": "Chiều cao",
+ "link_url_help": "Địa chỉ mà liên kết dẫn tới.",
+ "link_text": "Văn bản liên kết",
+ "link_text_help": "Văn bản hiển thị dưới dạng liên kết.",
+ "link_open_help": "Mở liên kết trong tab mới"
+ },
+ "md-hints": {
+ "header_title": "Tiêu đề",
+ "header_hint": "# Văn bản của bạn",
+ "italic_title": "In nghiêng",
+ "italic_hint": "_Văn bản của bạn_",
+ "bold_title": "In đậm",
+ "bold_hint": "**Văn bản của bạn**",
+ "strikethrough_title": "Gạch ngang",
+ "strikethrough_hint": "~~Văn bản của bạn~~",
+ "blockquote_title": "Trích dẫn",
+ "blockquote_hint": "> Văn bản của bạn",
+ "code_title": "Mã nguồn",
+ "code_hint": "```Văn bản của bạn```",
+ "link_title": "Liên kết",
+ "link_hint": "[Văn bản của bạn](url)",
+ "image_title": "Ảnh",
+ "image_hint": "",
+ "list_title": "Mục danh sách",
+ "list_hint": "- Văn bản của bạn",
+ "numbered-list_title": "Danh sách đánh số",
+ "numbered-list_hint": "1. Văn bản của bạn",
+ "documentation": "Tài liệu",
+ "documentation_link": "https://diplodoc.com/docs/en/syntax/"
+ },
+ "menubar": {
+ "bold": "In đậm",
+ "code": "Mã nguồn",
+ "code_inline": "Mã nội dòng",
+ "codeblock": "Khối mã",
+ "colorify": "Màu chữ",
+ "colorify__color_blue": "Xanh dương",
+ "colorify__color_default": "Mặc định",
+ "colorify__color_gray": "Xám",
+ "colorify__color_green": "Xanh lá",
+ "colorify__color_orange": "Cam",
+ "colorify__color_red": "Đỏ",
+ "colorify__color_violet": "Tím",
+ "colorify__color_yellow": "Vàng",
+ "colorify__group_text": "Văn bản",
+ "cut": "Cắt",
+ "emoji": "Biểu tượng cảm xúc",
+ "emoji__hint": "Biểu tượng có thể thêm ở WYSIWYG hoặc bằng markup",
+ "heading": "Tiêu đề",
+ "heading1": "Tiêu đề 1",
+ "heading2": "Tiêu đề 2",
+ "heading3": "Tiêu đề 3",
+ "heading4": "Tiêu đề 4",
+ "heading5": "Tiêu đề 5",
+ "heading6": "Tiêu đề 6",
+ "hrule": "Ngăn cách",
+ "image": "Ảnh",
+ "italic": "In nghiêng",
+ "link": "Liên kết",
+ "list": "Danh sách",
+ "list__action_lift": "Nâng mục",
+ "list__action_sink": "Hạ mục",
+ "list_action_disabled": "Mâu thuẫn với logic danh sách",
+ "mark": "Đánh dấu",
+ "mono": "Chữ monospace",
+ "more_action": "Thêm hành động",
+ "note": "Ghi chú",
+ "olist": "Danh sách đánh số",
+ "quote": "Trích dẫn",
+ "redo": "Làm lại",
+ "strike": "Gạch ngang",
+ "table": "Bảng",
+ "text": "Văn bản",
+ "ulist": "Danh sách gạch đầu dòng",
+ "underline": "Gạch dưới",
+ "undo": "Hoàn tác"
+ },
+ "placeholder": {
+ "doc_empty": "Gõ / để dùng lệnh nhanh...",
+ "checkbox": "Nhập mô tả nhiệm vụ...",
+ "deflist_term": "Thuật ngữ",
+ "deflist_desc": "Mô tả định nghĩa",
+ "heading": "Tiêu đề",
+ "cut_title": "Tiêu đề",
+ "cut_content": "Nội dung hiển thị khi nhấp",
+ "note_title": "Tiêu đề",
+ "note_content": "Nội dung ghi chú",
+ "table_cell": "Nội dung ô",
+ "select_filter": "Tìm ngôn ngữ..."
+ },
+ "search": {
+ "label_case-sensitive": "Phân biệt chữ hoa/thường",
+ "label_whole-word": "Nguyên từ",
+ "title": "Tìm trong mã"
+ },
+ "suggest": {
+ "empty-msg": "Không tìm thấy"
+ },
+ "widgets": {
+ "image": "Thêm ảnh",
+ "link": "Thêm liên kết"
+ },
+ "yfm-note": {
+ "info": "Ghi chú",
+ "tip": "Mẹo",
+ "warning": "Cảnh báo",
+ "alert": "Thông báo",
+ "remove": "Xóa"
+ },
+ "yfm-table": {
+ "column.add.before": "Thêm cột trước",
+ "column.add.after": "Thêm cột sau",
+ "column.remove": "Xóa cột",
+ "column.remove.multiple": "Xóa các cột",
+ "row.add.before": "Thêm hàng trước",
+ "row.add.after": "Thêm hàng sau",
+ "row.remove": "Xóa hàng",
+ "row.remove.multiple": "Xóa các hàng",
+ "cells.clear": "Xóa ô",
+ "table.remove": "Xóa bảng",
+ "table.menu.cell.align.left": "Căn trái nội dung ô",
+ "table.menu.cell.align.right": "Căn phải nội dung ô",
+ "table.menu.cell.align.center": "Căn giữa nội dung ô",
+ "table.menu.row.add": "Thêm hàng sau",
+ "table.menu.row.remove": "Xóa hàng",
+ "table.menu.column.add": "Thêm cột sau",
+ "table.menu.column.remove": "Xóa cột",
+ "table.menu.convert.yfm": "Chuyển sang bảng YFM",
+ "table.menu.table.remove": "Xóa bảng"
+ }
+}
diff --git a/server/api/controllers/access-tokens/accept-terms.js b/server/api/controllers/access-tokens/accept-terms.js
index 9e21a9f0..b8bf10f6 100644
--- a/server/api/controllers/access-tokens/accept-terms.js
+++ b/server/api/controllers/access-tokens/accept-terms.js
@@ -35,7 +35,7 @@
* example: 940226c4c41f51afe3980ceb63704e752636526f4c52a4ea579e85b247493d94
* initialLanguage:
* type: string
- * enum: [ar-YE, bg-BG, ca-ES, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, zh-CN, zh-TW]
+ * enum: [ar-YE, bg-BG, ca-ES, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, vi-VN, zh-CN, zh-TW]
* nullable: true
* description: Preferred language for user interface and notifications (used only if user language is not set)
* example: en-US
diff --git a/server/api/controllers/users/create.js b/server/api/controllers/users/create.js
index 2382b79a..747ae2c3 100755
--- a/server/api/controllers/users/create.js
+++ b/server/api/controllers/users/create.js
@@ -67,7 +67,7 @@
* example: Acme Corporation
* language:
* type: string
- * enum: [ar-YE, bg-BG, ca-ES, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, zh-CN, zh-TW]
+ * enum: [ar-YE, bg-BG, ca-ES, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, vi-VN, zh-CN, zh-TW]
* nullable: true
* description: Preferred language for user interface and notifications (if null - will be set automatically on the first login)
* example: en-US
diff --git a/server/api/controllers/users/update.js b/server/api/controllers/users/update.js
index 19cebcb4..415f9c1b 100755
--- a/server/api/controllers/users/update.js
+++ b/server/api/controllers/users/update.js
@@ -56,7 +56,7 @@
* example: Acme Corporation
* language:
* type: string
- * enum: [ar-YE, bg-BG, ca-ES, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, zh-CN, zh-TW]
+ * enum: [ar-YE, bg-BG, ca-ES, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, vi-VN, zh-CN, zh-TW]
* description: Preferred language for user interface and notifications
* example: en-US
* apiKey:
diff --git a/server/api/models/User.js b/server/api/models/User.js
index 818235b0..df949494 100755
--- a/server/api/models/User.js
+++ b/server/api/models/User.js
@@ -96,7 +96,7 @@
* example: Acme Corporation
* language:
* type: string
- * enum: [ar-YE, bg-BG, ca-ES, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, zh-CN, zh-TW]
+ * enum: [ar-YE, bg-BG, ca-ES, cs-CZ, da-DK, de-DE, el-GR, en-GB, en-US, es-ES, et-EE, fa-IR, fi-FI, fr-FR, hu-HU, id-ID, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, pt-PT, ro-RO, ru-RU, sk-SK, sr-Cyrl-RS, sr-Latn-RS, sv-SE, tr-TR, uk-UA, uz-UZ, vi-VN, zh-CN, zh-TW]
* nullable: true
* description: Preferred language for user interface and notifications (personal field)
* example: en-US
@@ -237,6 +237,7 @@ const LANGUAGES = [
'tr-TR',
'uk-UA',
'uz-UZ',
+ 'vi-VN',
'zh-CN',
'zh-TW',
];
diff --git a/server/config/i18n.js b/server/config/i18n.js
index 6eede354..8efcff5b 100644
--- a/server/config/i18n.js
+++ b/server/config/i18n.js
@@ -52,6 +52,7 @@ module.exports.i18n = {
'tr-TR',
'uk-UA',
'uz-UZ',
+ 'vi-VN',
'zh-CN',
'zh-TW',
],
diff --git a/server/config/locales/vi-VN.json b/server/config/locales/vi-VN.json
new file mode 100644
index 00000000..e68bb900
--- /dev/null
+++ b/server/config/locales/vi-VN.json
@@ -0,0 +1,19 @@
+{
+ "Archive": "Lưu trữ",
+ "Card Created": "Thẻ đã được tạo",
+ "Card Moved": "Thẻ đã được di chuyển",
+ "copy": "bản sao",
+ "New Comment": "Bình luận mới",
+ "Test Title": "Tiêu đề thử nghiệm",
+ "This is a test text message!": "Đây là tin nhắn văn bản thử nghiệm!",
+ "This is a *test* **markdown** `message`!": "Đây là *tin nhắn* **markdown** `thử nghiệm`!",
+ "This is a test html message!": "Đây là tin nhắn html thử nghiệm!",
+ "Trash": "Thùng rác",
+ "You Were Added to Card": "Bạn đã được thêm vào thẻ",
+ "You Were Mentioned in Comment": "Bạn đã được nhắc đến trong bình luận",
+ "%s added you to %s on %s": "%s đã thêm bạn vào %s vào %s",
+ "%s created %s in %s on %s": "%s đã tạo %s trong %s vào %s",
+ "%s left a new comment to %s on %s": "%s đã để lại bình luận mới cho %s vào %s",
+ "%s mentioned you in %s on %s": "%s đã nhắc đến bạn trong %s vào %s",
+ "%s moved %s from %s to %s on %s": "%s đã di chuyển %s từ %s đến %s vào %s"
+}