Jelajahi Sumber

feat: 实现多语言文件

Jack Zhou 2 minggu lalu
induk
melakukan
30b45f171e
20 mengubah file dengan 1130 tambahan dan 153 penghapusan
  1. 2 2
      src/App.vue
  2. 64 27
      src/locales/en.json
  3. 7 7
      src/locales/index.ts
  4. 942 18
      src/locales/zh-cn.json
  5. 1 1
      src/views/DestinationDelivery/src/components/TableView/src/TableView.vue
  6. 11 11
      src/views/SystemSettings/src/SystemSettings.vue
  7. 18 13
      src/views/SystemSettings/src/components/CreateNewrule/src/CreateNewrule.vue
  8. 1 1
      src/views/SystemSettings/src/components/MonitoringTable/src/MonitoringTable.vue
  9. 1 1
      src/views/SystemSettings/src/components/SettingTable/src/SettingTable.vue
  10. 16 16
      src/views/TemplateManagement/src/components/CreateReportTemplate/src/CreateReportTemplate.vue
  11. 21 21
      src/views/TemplateManagement/src/components/CreateReportTemplate/src/components/ReportFieldsConfiguration.vue
  12. 5 5
      src/views/Tracking/src/components/PublicTracking/src/components/BasicInformation.vue
  13. 9 9
      src/views/Tracking/src/components/PublicTracking/src/components/PublicTrackingDetail.vue
  14. 3 3
      src/views/Tracking/src/components/PublicTracking/src/components/ShareLinkDialog.vue
  15. 4 4
      src/views/Tracking/src/components/TrackingDetail/src/components/AddReferenceDialog.vue
  16. 1 1
      src/views/Tracking/src/components/TrackingDetail/src/components/AttachmentView.vue
  17. 6 3
      src/views/Tracking/src/components/TrackingDetail/src/components/ContainersView.vue
  18. 3 3
      src/views/Tracking/src/components/TrackingDetail/src/components/EmailDrawer.vue
  19. 4 1
      src/views/Tracking/src/components/TrackingDetail/src/components/MilestonesTable.vue
  20. 11 6
      src/views/Tracking/src/components/TrackingDetail/src/components/RoutesView.vue

+ 2 - 2
src/App.vue

@@ -19,8 +19,8 @@ langValue.value = localStorage.getItem('lang') || 'English'
 const languageChangetest = (label: string) => {
   if (label === 'Chinese') {
     // current.$i18n.locale = 'zh_TW'
-    locale.value = 'zh_TW' // 修改 locale 的值
-    langStore.setLang('Chinese')
+    locale.value = 'en_US' // 修改 locale 的值
+    langStore.setLang('English')
   } else {
     // current.$i18n.locale = 'en_US'
     locale.value = 'en_US'

+ 64 - 27
src/locales/en.json

@@ -194,11 +194,14 @@
     "supportedFormats": "Supported formats: .pdf, .xlsx, .docx",
     "maximumSize": "Maximum Size: 5MB;",
     "maximumNumber": "Maximum Number: 5 files",
+    "allowedFileTypes": "The file types allowed for upload are: PDF, XLSX and DOCX.",
+    "communicationToKln": "Communication to KLN:",
+    "cc": "CC",
+    "separatedByTip": "Separated by ;",
+    "fileSizeLimit": "File size must not exceed 5MB!",
     "selectFileTypeAndUpload": "Please select file type and upload file",
     "uploadSuccessfully": "Upload successfully",
     "uploadFailed": "Upload failed",
-    "allowedFileTypes": "The file types allowed for upload are: PDF, XLSX and DOCX.",
-    "fileSizeLimit": "File size must not exceed 5MB!",
     "selectAtLeastOneFileToDownload": "Please select at least one file to download.",
     "attachmentSummary": "Attachment Summary",
     "downloadSelected": "Download Selected ({count})",
@@ -237,16 +240,34 @@
     "pleaseSelect": "Please select...",
     "pickDate": "Pick a Date",
     "pleaseLoginFirst": "Please login first",
-    "origin": "Origin",
-    "destination": "Destination",
-    "etdAtd": "ETD/ATD",
-    "etaAta": "ETA/ATA",
     "basicInformation": "Basic Information",
     "businessPartners": "Business Partners",
     "containers": "Containers",
     "milestones": "Milestones",
     "routes": "Routes",
     "attachment": "Attachment",
+    "legsCount": "Total number of legs: {count}",
+    "leg": "Leg {count}",
+    "origin": "Origin",
+    "destination": "Destination",
+    "etdAtd": "ETD / ATD",
+    "etaAta": "ETA / ATA",
+    "vesselAirline": "Vessel / Airline",
+    "voyageFlight": "Voyage / Flight",
+    "mawbMblNo": "MAWB/MBL No.",
+    "hawbHblNo": "HAWB/HBL No.",
+    "bookingNo": "Booking No.",
+    "poNo": "PO No.",
+    "refNo": "Ref No.",
+    "quantityUnit": "Quantity / Unit",
+    "gWeight": "G. Weight",
+    "chWeight": "Ch. Weight",
+    "volume": "Volume",
+    "marks": "Marks",
+    "remark": "Remark",
+    "packing": "Packing",
+    "marksAndDescription": "Marks and Description",
+    "seeAll": "See All",
     "tdShare": "Share",
     "tdHouseNo": "House No.",
     "tdAmsIsf": "AMS/ISF",
@@ -358,27 +379,34 @@
     "reportFieldsConfigurationNewFieldNameRequired": "Please enter the new field name.",
     "reportFieldsConfigurationFixedValueRequired": "Please enter the fixed value.",
     "reportFieldsConfigurationReportLevelRequired": "Please select the report level.",
-    "createReportTemplateReportNameRequired": "Please enter the Report Name.",
-    "createReportTemplateReportLevelRequired": "Please enter the Report Level",
-    "createReportTemplateReportDescriptionRequired": "Please enter the Report Description.",
-    "createReportTemplateSavedSuccessfully": "Report Template saved successfully!",
-    "createReportTemplateAddNewFieldTitle": "Add New Field",
-    "createReportTemplateNewFieldNameLabel": "New Field Name",
-    "createReportTemplateReportNameLabel": "Report Name",
-    "createReportTemplateReportLevelLabel": "Report Level",
-    "createReportTemplateReportDescriptionLabel": "Report Description",
-    "createReportTemplateBlankText": "Blank",
-    "createReportTemplateFixedValueText": "Fixed Value",
-    "createReportTemplateFieldValueLabel": "Field Value",
-    "createReportTemplateFixedValueLabel": "Fixed Value",
-    "createReportTemplateMappingTitle": "Mapping (Field: Final Destination)",
-    "createReportTemplateSystemValueLabel": "System Value",
-    "createReportTemplateOutputValueLabel": "Output Value",
-    "createReportTemplateAddMapping": "Add Mapping",
-    "createReportTemplateFilter": "Filter",
-    "createReportTemplateSort": "Sort",
-    "createReportTemplateCancel": "Cancel",
-    "createReportTemplateApply": "Apply"
+    "reportNameRequired": "Please enter the Report Name.",
+    "reportDescriptionRequired": "Please enter the Report Description.",
+    "savedSuccessfully": "Report Template saved successfully!",
+    "newFieldNameRequired": "Please enter a field name.",
+    "fixedValueRequired": "Please enter a fixed value.",
+    "reportLevelRequired": "Please enter the Report Level",
+    "reportFieldsConfigurationTitle": "Report Fields Configuration",
+    "addNewField": "Add New Field",
+    "selectField": "Select Field",
+    "addEditField": "Add/Edit Field",
+    "noFieldSelectedTip": "No field selected. click \"Add Field\" to get started.",
+    "reportNameLabel": "Report Name",
+    "reportLevelLabel": "Report Level",
+    "reportDescriptionLabel": "Report Description",
+    "filter": "Filter",
+    "sort": "Sort",
+    "addNewFieldTitle": "Add New Field",
+    "newFieldNameLabel": "New Field Name",
+    "fieldValueLabel": "Field Value",
+    "blankText": "Blank",
+    "fixedValueText": "Fixed Value",
+    "fixedValueLabel": "Fixed Value",
+    "mappingTitle": "Mapping (Field: Final Destination)",
+    "systemValueLabel": "System Value",
+    "outputValueLabel": "Output Value",
+    "addMapping": "Add Mapping",
+    "cancel": "Cancel",
+    "apply": "Apply"
   },
   "reportSchedule": {
     "scheduleConfiguration": "Schedule Configuration - {name}",
@@ -865,6 +893,7 @@
     "unsavedChanges": "There are unsaved changes.",
     "confirmLeavePage": "Are you sure you want to leave this page?",
     "unsavedChangesTitle": "Unsaved Changes",
+    "pleaseSelectNotificationEventsFirst": "Please select Notification Events first",
     "specificRule": "Specific Rule",
     "singleDimension": "Single Dimension",
     "defaultRule": "Default Rule",
@@ -885,6 +914,14 @@
     "add": "Add",
     "configureRegionsAndTimeSlots": "Configure available destination delivery regions and time slots.",
     "addRule": "Add Rule",
+    "customizeYourShipmentTrackingPreferences": "Customize your shipment tracking preferences.",
+    "event": "Event",
+    "eventDetails": "Event Details",
+    "frequency": "Frequency",
+    "methods": "Methods",
+    "hbolHawb": "HBOL/HAWB",
+    "etd": "ETD",
+    "recentMilestone": "Recent Milestone",
     "deleteRule": "Delete Rule",
     "confirmDeleteRule": "Are you sure to delete this notification event?",
     "configuration": "Configuration",

+ 7 - 7
src/locales/index.ts

@@ -1,23 +1,23 @@
 // lang -> index.ts
 import { createI18n } from 'vue-i18n'
-import ch from './zh-tw.json'
-import zhHans from './zh-cn.json'
+// import ch from './zh-tw.json'
+// import zhHans from './zh-cn.json'
 import en from './en.json'
-import zhCN from 'vxe-pc-ui/lib/language/zh-CN'
+// import zhCN from 'vxe-pc-ui/lib/language/zh-CN'
 import enUS from 'vxe-pc-ui/lib/language/en-US'
 
 /* 这里必须是messages名称 */
 const messages: any = {
-  zh_CN: { ...zhCN, ...zhHans, ...en },
-  zh_TW: { ...zhCN, ...ch, ...en },
-  en_US: { ...enUS, ...en }
+  // zh_CN: { ...en, ...zhCN, ...zhHans },
+  // zh_TW: { ...en, ...zhCN, ...ch },
+  en_US: { ...en, ...enUS }
 }
 messages.en_US.vxe.table.seqTitle = 'seq'
 
 const i18n = createI18n({
   legacy: false, // 使用 Composition API 模式,则需要将其设置为false
   globalInjection: true, //全局生效$t
-  locale: 'zh_CN', // 默认使用简体中文
+  locale: 'en_US', // 默认使用简体中文
   fallbackLocale: 'en_US', // 简体未覆盖时回退英文,避免落回繁体
   messages // 使用数据源
 })

+ 942 - 18
src/locales/zh-cn.json

@@ -1,21 +1,945 @@
 {
   "login": {
-    "username": "用戶名",
-    "password": "密碼",
-    "login": "登錄",
-    "forgotPassword": "忘記密碼?",
-    "setPassword": "設置密碼",
-    "activateAccount": "激活賬戶",
-    "noAccount": "沒有賬戶?",
-    "registerNow": "立即註冊",
-    "captchaPlaceholder": "請輸入驗證碼",
-    "sendCaptcha": "發送驗證碼",
-    "resendCaptcha": "重新發送驗證碼",
-    "captchaSent": "驗證碼已發送至您的郵箱",
-    "resetPassword": "重置密碼",
-    "newPassword": "新密碼",
-    "confirmNewPassword": "確認新密碼",
-    "passwordMismatch": "密碼不匹配",
-    "activationEmailSent": "激活郵件已發送至您的郵箱"
+    "username": "User Name",
+    "password": "Password",
+    "login": "Login",
+    "forgotPassword": "Forgot Password?",
+    "setPassword": "Set Password",
+    "activateAccount": "Activate Account",
+    "noAccount": "No account?",
+    "registerNow": "Register Now",
+    "captchaPlaceholder": "Please enter the captcha",
+    "sendCaptcha": "Send Captcha",
+    "resendCaptcha": "Resend Captcha",
+    "captchaSent": "Captcha has been sent to your email",
+    "resetPassword": "Reset Password",
+    "newPassword": "New Password",
+    "confirmNewPassword": "Confirm New Password",
+    "passwordMismatch": "Passwords do not match",
+    "activationEmailSent": "Activation email has been sent to your email",
+    "welcomeTitle": "Welcome to KLN Portal",
+    "welcomeSubtitle": "Login to your account",
+    "accountNotExist": "This account does not exist.",
+    "accountNotExistShort": "This account does not exist",
+    "loginBtn": "Login",
+    "resetPasswordTitle": "Reset Password",
+    "resetPasswordSubtitle": "We'll send your password to your email address.",
+    "setYourPassword": "Set Your Password",
+    "helloCreateNewPassword": "Hello {name}, please create a new password for your account.",
+    "userName": "User Name",
+    "emailAddress": "Email Address",
+    "sendResetLink": "Send Reset Link",
+    "backToLogin": "Back to login",
+    "usernamePlaceholder": "Please input user name",
+    "passwordPlaceholder": "Please input password",
+    "emailPlaceholder": "Please input your email address",
+    "oldPasswordPlaceholder": "Please input Old Password",
+    "newPasswordComplexityHint": "New password must contain both letter and numeral",
+    "confirmPasswordPlaceholder": "Please Confirm Password",
+    "rememberPassword": "Remember Password",
+    "incorrectPassword": "Incorrect password. Please try again.",
+    "incorrectEmail": "Incorrect email. Please try again.",
+    "passwordSecurityAlert": "Please change your password for security.",
+    "changePassword": "Change Password",
+    "passwordLength12to20": "Password length between 12 - 20",
+    "passwordMustContainUppercase": "Password must contain uppercase letters",
+    "passwordMustContainLowercase": "Password must contain lowercase letters",
+    "passwordMustContainNumber": "Password must contain numbers",
+    "setPasswordAndActivateAccount": "Set Password & Activate Account",
+    "firstLoginChangePassword": "First login, please change your password.",
+    "updateYourPassword": "Update your password",
+    "firstLoginPasswordUpdateTip": "To make your account secure, please create a new password to replace the temporary password you were given in the email.",
+    "passwordResetSuccessfully": "Password Reset Successfully",
+    "passwordResetSuccessfullyLine1": "Your password has been successfully reset.",
+    "passwordResetSuccessfullyLine2": "You can now log in using your email and your new password.",
+    "accountActivatedSuccessfully": "Account Activated Successfully",
+    "accountActivatedSuccessfullyLine1": "Your account has been successfully activated.",
+    "accountActivatedSuccessfullyLine2": "You can now log in using your email and the password you just created.",
+    "goToLogin": "Go to Login",
+    "pleaseLoginFirst": "Please login first"
+  },
+  "common": {
+    "search": "Search",
+    "searchUserNamePlaceholder": "Search user name",
+    "searchQuestionPlaceholder": "Search Question ID、User",
+    "searchChatPlaceholder": "Search Question ID、User",
+    "customerSearchPlaceholder": "Search by Customer code, Customer name",
+    "customerType": "Customer Type",
+    "controllingCustomer": "Controlling Customer",
+    "billTo": "Bill to",
+    "notifyParty": "Notify Party",
+    "cancel": "Cancel",
+    "save": "Save",
+    "reset": "Reset",
+    "ok": "OK",
+    "change": "Change",
+    "all": "All",
+    "update": "Update",
+    "prompt": "Prompt",
+    "forgetPassword": "Forget Password",
+    "tooManyTries": "Oops, too many tries!",
+    "passwordAttemptsExceeded": "You have exceeded the maximum number of password attempts.",
+    "tryAgainInFiveMinutesOrReset": "Please try again in 5 minutes or click {action} to reset.",
+    "logout": "Logout",
+    "clearFilters": "Clear Filters",
+    "downloadFile": "Download File",
+    "selectedColumns": "Selected columns",
+    "downloadWithAllColumns": "Download with all columns",
+    "saveSuccess": "Saved successfully",
+    "requestFailedRetry": "The request failed. Please try again later",
+    "errorPleaseTryAgainLater": "Error! Please try again later.",
+    "copySuccess": "Copy success",
+    "invalidToken": "Invalid token",
+    "details": "Details",
+    "description": "Description",
+    "userType": "User Type",
+    "questionType": "Question Type",
+    "answerType": "Answer Type",
+    "answerSatisfaction": "Answer Satisfaction",
+    "page": "Page",
+    "chatLog": "Chat Log",
+    "customer": "Customer",
+    "employee": "Employee",
+    "predefinedQuestion": "Predefined Question",
+    "freeText": "Free Text",
+    "suspend": "Suspend",
+    "timeout": "Timeout",
+    "predefinedTemplate": "Predefined Template",
+    "aiAnswer": "AI Answer",
+    "null": "Null",
+    "good": "Good",
+    "notGood": "Not Good",
+    "responseDuration": "Response Duration",
+    "schedule": "Schedule",
+    "failedToLoadOptions": "Failed to load options",
+    "stations": "Stations",
+    "bookingWindow": "Booking Window",
+    "operation": "Operation",
+    "configureRegionsAndTimeSlots": "Configure available destination delivery regions and time slots.",
+    "deleteRule": "Delete Rule",
+    "confirmDeleteRule": "Are you sure to delete this notification event?",
+    "failedToLoadData": "Failed to load data",
+    "cannotAddDuplicateCities": "Cannot add duplicate cities.",
+    "inputCountryCityUncode": "Please input country/city/uncode",
+    "country": "Country",
+    "city": "City",
+    "uncode": "Uncode",
+    "etd": "ETD",
+    "eta": "ETA",
+    "total": "Total",
+    "noData": "No data",
+    "loading": "Loading...",
+    "input": "Input",
+    "sliderVerifyTipLine1": "Please drag the slider below to complete the",
+    "sliderVerifyTipLine2": "verification to ensure normal access",
+    "swipeToVerify": "Swipe to verify",
+    "verificationSuccessful": "Verification successful",
+    "verificationFailed": "Verification failed",
+    "transportMode": "Transport Mode",
+    "regionalSolutions": "REGIONAL SOLUTIONS",
+    "selectAll": "Select All",
+    "select": "Select",
+    "dateRange": "Date Range",
+    "dateType": "Date Type",
+    "pleaseSelectDateType": "Please Select Date Type",
+    "moreDateType": "More Date Type",
+    "moreFilters": "More Filters",
+    "general": "General",
+    "incoterms": "Incoterms",
+    "service": "Service",
+    "parties": "Parties",
+    "places": "Places",
+    "transportation": "Transportation",
+    "pleaseSelectDateRange": "Please Select Date Range",
+    "pleaseSelectService": "Please Select Service",
+    "seeAll": "See All",
+    "partyType": "Party Type",
+    "partyDetails": "Party Details",
+    "pleaseSelectPartyType": "Please Select Party Type",
+    "pleaseInputPartyDetails": "Please Input Party Details",
+    "placesType": "Places Type",
+    "placesDetails": "Places Details",
+    "pleaseInputPlacesDetails": "Please Input Places Details",
+    "title": "Title",
+    "noResultsFound": "No Results Found",
+    "emptyResultLine1": "We didn't find any search results,",
+    "emptyResultLine2": "please try to adjust your search keywords.",
+    "pageGuide": "Page Guide"
+  },
+  "tracking": {
+    "title": "Tracking",
+    "searchPlaceholder": "Enter Booking/HBL/PO/Container/Carrier Booking No. ",
+    "referenceTip": "We support the following references number to find bookings: Booking No./HAWB No./MAWB No./PO No./Carrier Booking No./Contract No./File No./Quote No.",
+    "selectRecordForAttachmentDownload": "Please select at least one record to download attachments",
+    "download": "Download",
+    "downloadShipmentDetails": "Download Shipment Details",
+    "downloadAttachments": "Download Attachments",
+    "referenceTipForTracking": "We support the following references number to find tracking:",
+    "subscribe": "Subscribe",
+    "vgm": "VGM",
+    "publicSearchPlaceholder": "Enter Booking/HBL/MBL/PO/Container No.",
+    "publicReferenceTipTitle": "We support the following references number to find shipment:",
+    "publicReferenceTipList": "· Tracking No./Booking No./HAWB No./MAWB No./PO No./Quote No./Invoice No./Container No.",
+    "multipleResultsTitle": "Sorry,Multiple results",
+    "multipleResultsLine1": "To correctly display the details page,",
+    "multipleResultsLine2": "please search using the HBL No. Thank you.",
+    "selectDataOnShipmentList": "Select data on your shipment list",
+    "downloadWithSelectedColumns": "Download with selected columns",
+    "refNoDialogTitle": "Ref No.",
+    "selectReferenceTypePlaceholder": "Select Reference Type",
+    "enterRefNoPlaceholder": "Enter Ref No.",
+    "uploadFiles": "Upload Files",
+    "upload": "Upload",
+    "fileType": "File Type",
+    "supportedFormats": "Supported formats: .pdf, .xlsx, .docx",
+    "maximumSize": "Maximum Size: 5MB;",
+    "maximumNumber": "Maximum Number: 5 files",
+    "selectFileTypeAndUpload": "Please select file type and upload file",
+    "uploadSuccessfully": "Upload successfully",
+    "uploadFailed": "Upload failed",
+    "allowedFileTypes": "The file types allowed for upload are: PDF, XLSX and DOCX.",
+    "fileSizeLimit": "File size must not exceed 5MB!",
+    "selectAtLeastOneFileToDownload": "Please select at least one file to download.",
+    "attachmentSummary": "Attachment Summary",
+    "downloadSelected": "Download Selected ({count})",
+    "noFile": "No file",
+    "attachmentNumber": "Attachment {no}",
+    "defaultSettings": "Default Settings",
+    "settingsSavedSuccessfully": "Settings saved successfully",
+    "submitter": "Submitter",
+    "signature": "Signature",
+    "authorizedEmail": "Authorized Email",
+    "authorizedTel": "Authorized Tel",
+    "addVgm": "Add VGM",
+    "generalInformation": "General Information",
+    "detailInformation": "Detail Information",
+    "isSend": "Is Send",
+    "defaultSetting": "Default Setting",
+    "hblNo": "HBL No.",
+    "carrierBookingNo": "Carrier Booking No.",
+    "vessel": "Vessel",
+    "voyage": "Voyage",
+    "etd": "ETD",
+    "eta": "ETA",
+    "lastUpdatedUser": "Last Updated User",
+    "lastUpdatedTime": "Last Updated Time",
+    "noAccess": "No access",
+    "drawerTitleBoth": "AMS/ISF",
+    "drawerTitleAms": "AMS",
+    "drawerTitleIsf": "ISF",
+    "amsM1Log": "AMS-M1 Log",
+    "isfLog": "ISF Log",
+    "copiedToClipboard": "Copied to clipboard",
+    "failedToCopy": "Failed to copy",
+    "tips": "Copy the link to share this shipment with anyone.",
+    "copyLink": "Copy Link",
+    "pleaseEnter": "Please enter...",
+    "pleaseSelect": "Please select...",
+    "pickDate": "Pick a Date",
+    "pleaseLoginFirst": "Please login first",
+    "basicInformation": "Basic Information",
+    "businessPartners": "Business Partners",
+    "containers": "Containers",
+    "milestones": "Milestones",
+    "routes": "Routes",
+    "attachment": "Attachment",
+    "legsCount": "Total number of legs: {count}",
+    "leg": "Leg {count}",
+    "origin": "Origin",
+    "destination": "Destination",
+    "etdAtd": "ETD / ATD",
+    "etaAta": "ETA / ATA",
+    "vesselAirline": "Vessel / Airline",
+    "voyageFlight": "Voyage / Flight",
+    "mawbMblNo": "MAWB/MBL No.",
+    "hawbHblNo": "HAWB/HBL No.",
+    "bookingNo": "Booking No.",
+    "poNo": "PO No.",
+    "refNo": "Ref No.",
+    "quantityUnit": "Quantity / Unit",
+    "gWeight": "G. Weight",
+    "chWeight": "Ch. Weight",
+    "volume": "Volume",
+    "marks": "Marks",
+    "remark": "Remark",
+    "packing": "Packing",
+    "marksAndDescription": "Marks and Description",
+    "seeAll": "See All",
+    "tdShare": "Share",
+    "tdHouseNo": "House No.",
+    "tdAmsIsf": "AMS/ISF",
+    "tdAddReference": "Add Reference",
+    "tdReferenceType": "Reference Type",
+    "tdRefNo": "Ref No.",
+    "tdAction": "Action",
+    "ptMawbMblNo": "MAWB/MBL No.",
+    "ptHawbHblNo": "HAWB/HBL No.",
+    "ptBookingNo": "Booking No.",
+    "ptPoNo": "PO No.",
+    "ptVesselAirline": "Vessel / Airline",
+    "ptVoyageFlight": "Voyage / Flight",
+    "ptOriginAgent": "Origin Agent",
+    "ptDestinationAgent": "Destination Agent",
+    "ptQuantityUnit": "Quantity / Unit",
+    "ptGWeight": "G. Weight",
+    "ptChWeight": "Ch. Weight",
+    "ptVolume": "Volume",
+    "ptMarks": "Marks",
+    "ptDescription": "Description"
+  },
+  "systemMessage": {
+    "title": "System Message",
+    "eventNotifications": "Event Notifications",
+    "allNotifications": "All Notifications",
+    "unread": "Unread",
+    "read": "Read",
+    "featureUpdate": "Feature Update",
+    "milestoneUpdate": "Milestone Update",
+    "containerStatusUpdate": "Container Status Update",
+    "departureArrivalDelay": "Departure/Arrival Delay",
+    "etdEtaChange": "ETD/ETA Change"
+  },
+  "layout": {
+    "logoutConfirm": "Are you sure you want to logout?",
+    "changePasswordTitle": "Change Password",
+    "passwordUpdatedSuccessfully": "Password updated successfully",
+    "passwordLength12to20": "Password length between 12 - 20",
+    "passwordMustContainUppercase": "Password must contain uppercase letters",
+    "passwordMustContainLowercase": "Password must contain lowercase letters",
+    "passwordMustContainNumber": "Password must contain numbers",
+    "downloadKLNPortalTitle": "Download KLN Portal",
+    "iphoneAppStore": "iPhone App Store",
+    "androidPlayStore": "Android-Play Store",
+    "androidChinaUser": "Android-China User",
+    "viewAsCustomer": "View as Customer",
+    "selectCustomer": "Select customer",
+    "noData": "no data",
+    "passwordExpiredUnavailable": "This account's password has expired and is currently unavailable. Please select a different customer account to continue.",
+    "accountNotActivated": "This account has not been activated yet. Please select a different customer account to continue.",
+    "accountDisabled": "This account has been disabled and is no longer accessible. Please select a different customer account to continue.",
+    "operationFailedRetry": "Operation failed, please try again later",
+    "customizeColumns": "Customize Columns",
+    "openDetailedPage": "Open Detailed Page",
+    "closeDetailedPage": "Close Detailed Page",
+    "sendEmail": "Send Email",
+    "publicTracking": "Public Tracking",
+    "addReference": "Add Reference",
+    "uploadFile": "Upload File",
+    "amsIsf": "AMS/ISF",
+    "changePassword": "Change Password"
+  },
+  "report": {
+    "title": "Report",
+    "searchPlaceholder": "Search Report Name",
+    "excelFile": "Excel(.xlsx)",
+    "csvFile": "CSV(.csv)",
+    "downloadReport": "Download Report",
+    "manageFields": "Manage Fields",
+    "filters": "Filters",
+    "pleaseEnter": "Please enter...",
+    "pleaseSelect": "Please select...",
+    "to": "To",
+    "startDate": "Start date",
+    "endDate": "End date",
+    "manageReportFields": "Manage Report Fields",
+    "showAll": "Show All",
+    "hideAll": "Hide All",
+    "of": "of",
+    "fieldsVisible": "Fields Visible",
+    "systemName": "System Name",
+    "displayNameInReport": "Display Name in Report",
+    "apply": "Apply",
+    "selectScheduleRuleValidityPeriod": "Please select the Schedule Rule Validity Period",
+    "permanentValid": "Permanent Valid",
+    "activeContinuouslyTip": "Active continuously once enabled, until manually disabled or deleted.",
+    "customPeriod": "Custom Period",
+    "onlyExecuteInSpecifiedPeriodTip": "Only automatically execute during specified time period.",
+    "effectiveStartDate": "Effective Start Date",
+    "effectiveEndDate": "Effective End Date",
+    "pickDate": "Pick a Date"
+  },
+  "templateManagement": {
+    "title": "Report Template Management",
+    "createNew": "Create New Report Template",
+    "searchReportNamePlaceholder": "Search report name",
+    "isActivePlaceholder": "Is Active",
+    "applicationScopePlaceholder": "Application Scope",
+    "partyIdsPlaceholder": "Party IDs",
+    "active": "Active",
+    "inactive": "Inactive",
+    "allUsers": "All Users",
+    "specificUsers": "Specific Users",
+    "selectPartyIdsMulti": "Select Party IDs (Multi-select allowed)",
+    "selectGroupNameMulti": "Select Group Name (Multi-select allowed)",
+    "addEditFieldTitle": "Add/Edit Field",
+    "searchFieldPlaceholder": "Search field",
+    "reportFieldsConfigurationNewFieldNameRequired": "Please enter the new field name.",
+    "reportFieldsConfigurationFixedValueRequired": "Please enter the fixed value.",
+    "reportFieldsConfigurationReportLevelRequired": "Please select the report level.",
+    "createReportTemplateReportNameRequired": "Please enter the Report Name.",
+    "createReportTemplateReportLevelRequired": "Please enter the Report Level",
+    "createReportTemplateReportDescriptionRequired": "Please enter the Report Description.",
+    "createReportTemplateSavedSuccessfully": "Report Template saved successfully!",
+    "createReportTemplateAddNewFieldTitle": "Add New Field",
+    "createReportTemplateNewFieldNameLabel": "New Field Name",
+    "createReportTemplateReportNameLabel": "Report Name",
+    "createReportTemplateReportLevelLabel": "Report Level",
+    "createReportTemplateReportDescriptionLabel": "Report Description",
+    "createReportTemplateBlankText": "Blank",
+    "createReportTemplateFixedValueText": "Fixed Value",
+    "createReportTemplateFieldValueLabel": "Field Value",
+    "createReportTemplateFixedValueLabel": "Fixed Value",
+    "createReportTemplateMappingTitle": "Mapping (Field: Final Destination)",
+    "createReportTemplateSystemValueLabel": "System Value",
+    "createReportTemplateOutputValueLabel": "Output Value",
+    "createReportTemplateAddMapping": "Add Mapping",
+    "createReportTemplateFilter": "Filter",
+    "createReportTemplateSort": "Sort",
+    "createReportTemplateCancel": "Cancel",
+    "createReportTemplateApply": "Apply"
+  },
+  "reportSchedule": {
+    "scheduleConfiguration": "Schedule Configuration - {name}",
+    "scheduleRuleValidityPeriod": "Schedule Rule Validity Period",
+    "reportDataTimeRange": "Report Data Time Range",
+    "reportDeliveryFrequencyEmail": "Report Delivery Frequency & Email Configuration",
+    "selectReportDeliveryFrequencyEmailConfig": "Please select the Report Delivery Frequency & Email Configuration",
+    "emailRecipientsPlaceholder": "Enter email address separated by commas",
+    "saveSuccess": "Save Success",
+    "selectReportDataTimeRange": "Please select the Report Data Time Range",
+    "dataTimeReferenceFieldTitle": "Data Time Reference Field Selection",
+    "dataRangeMethodTitle": "Data Range Configuration Method",
+    "dynamicRollingRange": "Dynamic Rolling Range",
+    "fixedRange": "Fixed Range",
+    "startDate": "Start Date",
+    "endDate": "End Date",
+    "past": "Past",
+    "future": "Future",
+    "dynamicRollingTooltipLine1": "Configuration: Past X days to Future Y days, always dynamically calculated based on current date when generating reports.",
+    "dynamicRollingTooltipLine2": "Usage: For example, setting 5 days to 3 days means the data range differs each time it's automatically generated. Used for short-cycle operational monitoring.",
+    "fixedRangeTooltipLine1": "Configuration: Specific start and end dates, always query this range when automatically generating reports.",
+    "fixedRangeTooltipLine2": "Example: Start date [2025-01-01], End date [2025-12-31]",
+    "thisMonth": "This Month",
+    "thisQuarter": "This Quarter",
+    "lastQuarter": "Last Quarter",
+    "lastYear": "Last Year"
+  },
+  "personalProfile": {
+    "basicInformation": "Basic Information",
+    "firstName": "First Name",
+    "lastName": "Last Name",
+    "email": "Email",
+    "password": "Password",
+    "passwordExpirePrefix": "Your password will be expire in",
+    "passwordExpireDays": "{n} day(s)",
+    "maskCustomerInformation": "Mask Customer Information",
+    "yes": "Yes",
+    "no": "No",
+    "saveSuccessfully": "Save successfully",
+    "saveFailed": "Save failed",
+    "personalPreferences": "Personal Preferences",
+    "dateAndTime": "Date & Time",
+    "numbersFormatNav": "Numbers Format",
+    "dateFormat": "Date Format",
+    "numbersFormat": "Numbers Format",
+    "numbersUsUk": "1,234.56 (US/UK)",
+    "numbersEuropean": "1.234,56 (European)"
+  },
+  "aiApiLog": {
+    "title": "AI API Log",
+    "searchPlaceholder": "Search Request ID, Question ID",
+    "aiModel": "AI Model",
+    "responseDuration": "Response Duration",
+    "selected": "Selected",
+    "requestContent": "Request Content",
+    "responseContent": "Response Content",
+    "selectDataOnLogList": "Select data on your Operation Log list:",
+    "downloadWithSelectedColumns": "Download with selected columns",
+    "deepseek": "Deepseek",
+    "claude": "Claude",
+    "greaterOrEqual": ">=",
+    "equal": "=",
+    "lessOrEqual": "<=",
+    "download": "Download"
+  },
+  "notificationRules": {
+    "shipmentRange": "Shipment Range",
+    "selectMilestone": "Select Milestone",
+    "selectContainerStatus": "Select Container Status",
+    "selectDelayedType": "Select Delayed Type",
+    "selectDelayedShipments": "Select Delayed Shipments",
+    "selectTimeType": "Select Time Type",
+    "notificationFrequency": "Notification Frequency",
+    "notificationMethod": "Notification Method",
+    "addedRules": "Added Rules",
+    "oceanShipments": "Ocean Shipments",
+    "airShipments": "Air Shipments",
+    "containerStatus": "Container Status",
+    "time": "Time",
+    "missing": "missing",
+    "duplicateRuleError": "Duplicate Rule Error.",
+    "duplicateRuleExactMatch": "This rule exactly matches an existing rule.",
+    "similarRuleDetected": "Similar Rule Detected",
+    "similarRuleExists": "A similar configuration rule already exists.",
+    "proceedCreateRule": "Would you like to proceed with creating this rule?",
+    "byEmail": "By Email",
+    "bySystemMessage": "By System Message",
+    "instantNotificationEachUpdate": "Instant notification for each update",
+    "dailySummary": "Daily Summary",
+    "weeklySummary": "Weekly Summary",
+    "selectTime": "Select Time",
+    "selectTimeZone": "Select Time Zone",
+    "selectDay": "Select Day",
+    "within": "within",
+    "days": "Day(s)",
+    "ocean": "Ocean",
+    "air": "Air",
+    "road": "Road",
+    "next30Days": "Next 30 days",
+    "next60Days": "Next 60 days",
+    "past10DaysToNext60Days": "Past 10 days to next 60 days",
+    "past30Days": "Past 30 days",
+    "customize": "Customize",
+    "minus": "minus",
+    "plus": "plus",
+    "currentTimeMinus": "Current time minus",
+    "currentTimePlus": "Current time plus",
+    "departureDelayedAtdEtd": "Departure Delayed (ATD-ETD)",
+    "arrivalDelayedAtaEta": "Arrival Delayed (ATA-ETA)",
+    "delayedTime": "Delayed Time",
+    "hours": "Hour(s)",
+    "notifyAllChanges": "Notify for all changes",
+    "notifyOnlyWhenTimeDifference": "Notify only when time difference",
+    "monday": "Monday",
+    "tuesday": "Tuesday",
+    "wednesday": "Wednesday",
+    "thursday": "Thursday",
+    "friday": "Friday",
+    "saturday": "Saturday",
+    "sunday": "Sunday"
+  },
+  "customizeColumns": {
+    "title": "Customize Columns",
+    "searchPlaceholder": "Search columns you preferred",
+    "selectedColumnsOnList": "Selected columns on your {type} list",
+    "booking": "booking",
+    "shipment": "shipment",
+    "resetToDefault": "Reset to default",
+    "tourStep1": "Drag items to the right group or click the Add icon to add columns to the {type} list.",
+    "tourStep2Line1": "Drag items to the left group or click the Remove icon to delete columns from the {type} list.",
+    "tourStep2Line2": "Drag items up or down to reorder the {type} list, or use the Move up and Move down icons.",
+    "gotIt": "Got it"
+  },
+  "aiRobot": {
+    "greeting": "Hi! I'm your Freight Assistant, always on call",
+    "frequentlyAskedQuestions": "Frequently Asked Questions",
+    "continueConversation": "Continue the conversation",
+    "disclaimerTitle": "Disclaimer",
+    "sidebarWindow": "Sidebar Window",
+    "maximizedWindow": "Maximized Window",
+    "collapsedToWidget": "Collapsed to Widget",
+    "answerInProgress": "Answer in progress, please wait.",
+    "cancelAnswer": "Cancel Answer",
+    "typeYourQuestionHere": "Type your question here...",
+    "contentGeneratedByAI": "Content is generated by Al, please check carefully!",
+    "importantNoticeAI": "Important Notice: AI-Generated Content",
+    "aiGeneratedResponses": "AI-Generated Responses:",
+    "dataPrivacySecurity": "Data Privacy & Security:",
+    "informationAccuracy": "Information Accuracy:",
+    "serviceLimitations": "Service Limitations:",
+    "aiAcknowledgement": "By using this AI assistant, you acknowledge these limitations and agree to use the information provided accordingly.",
+    "sidebarWindowTip": "Sidebar Window",
+    "maximizedWindowTip": "Maximized Window",
+    "collapsedToWidgetTip": "Collapsed to Widget"
+  },
+  "containerStatus": {
+    "container": "Container",
+    "trackingOnCarrierWebsite": "Tracking on carrier website:"
+  },
+  "notificationMessage": {
+    "latestStatusUpdates": "Latest Status Updates ({count})",
+    "departureDelay": "Departure Delay",
+    "etdChange": "ETD Change",
+    "arrivalDelay": "Arrival Delay",
+    "etaChange": "ETA Change",
+    "route": "Route",
+    "currentLeg": "Current Leg",
+    "onlyDisplayWithinThreeMonths": "Only display the message data within three months",
+    "smartAssistantContent": "Smart Assistant is live! Ask in natural language, get real-time shipment data with multi-language support.",
+    "smartNotificationContent": "Smart Notification is here! Four key event alerts with customizable rules and multi-channel delivery."
+  },
+  "vbox": {
+    "moveToTop": "Move to Top",
+    "moveUp": "Move Up",
+    "moveDown": "Move Down",
+    "moveToBottom": "Move to Bottom"
+  },
+  "moreFilters": {
+    "vessel": "Vessel",
+    "voyageFlight": "Voyage/Flight",
+    "inputVesselNameOrCode": "Please input vessel name or code",
+    "inputVoyageOrFlightNo": "Please input Voyage or flight no.",
+    "origin": "Origin",
+    "destination": "Destination",
+    "placeOfDelivery": "Place of delivery",
+    "placeOfReceipt": "Place of Receipt",
+    "portOfLoading": "Port of Loading",
+    "placeOfDischarge": "Place of Discharge",
+    "inputPlacesName": "Please input places name",
+    "morePlaceType": "More Place Type",
+    "shipperName": "Shipper Name",
+    "consigneeName": "Consignee Name",
+    "originAgent": "Origin Agent",
+    "destinationAgent": "Destination Agent",
+    "sales": "Sales",
+    "notifyParty": "Notify Party",
+    "billTo": "Bill to",
+    "destinationOperator": "Destination Operator",
+    "controllingCustomer": "Controlling Customer",
+    "inputShipperName": "Please input shipper name",
+    "inputConsigneeName": "Please input consignee name",
+    "inputPartyName": "Please input party name",
+    "morePartyType": "More Party Type"
+  },
+  "scoringGrade": {
+    "feedbackPlaceholder": "We look forward to hearing from you. Thank you for helping to build a better customer system.",
+    "shareYourFeedback": "Share Your Feedback",
+    "apologyMessage": "We are so sorry for the inconveniences. We value your experience immensely.",
+    "dissatisfiedAspectQuestion": "Could you please tell us which aspects of the system you are dissatisfied with?",
+    "thanksForSharing": "Thank you for sharing your thoughts with us. We value your experience greatly.",
+    "shareLikedAndImprovement": "Could you share what aspects you liked and what could be improved ?",
+    "thanksForSatisfiedRating": "Thank you very much for giving us a satisfied rating on our service or system.",
+    "whatMadeYouSatisfied": "We are curious to learn more about what specifically made you feel satisfied.",
+    "apologizeAgain": "Apologize once again for your experience.",
+    "appreciateFeedback": "We greatly appreciate your valuable time and feedback.",
+    "thanksPositiveEvaluation": "Once again, thank you for your positive evaluation.",
+    "satisfactionQuestion": "How satisfied are you with this system?",
+    "satisfactionQuestionWithSpace": "How satisfied are you with this system ?",
+    "shareMoreDetails": "Would you like to share more details with us?",
+    "hi": "Hi!",
+    "submitSuccessful": "Submit Successful",
+    "betterServiceCommitment": "We are committed to working hard to provide better services.",
+    "aspectFunctionality": "Functionality",
+    "aspectDataAccuracy": "Data accuracy",
+    "aspectLookAndFeel": "Look and feel",
+    "aspectEaseOfUse": "Ease of use",
+    "aspectWebsitePerformance": "Website performance",
+    "highlyDissatisfied": "Highly Dissatisfied",
+    "dissatisfied": "Dissatisfied",
+    "neutral": "Neutral",
+    "satisfied": "Satisfied",
+    "highlySatisfied": "Highly Satisfied"
+  },
+  "filterTags": {
+    "created": "Created",
+    "modified": "Modified",
+    "pending": "Pending",
+    "confirmed": "Confirmed",
+    "cancelled": "Cancelled",
+    "departed": "Departed",
+    "cargoReceived": "Cargo Received",
+    "arrived": "Arrived",
+    "completed": "Completed"
+  },
+  "dateRange": {
+    "startEtaTime": "Start ETA Time",
+    "endEtaTime": "End ETA Time",
+    "startAtaTime": "Start ATA Time",
+    "endAtaTime": "End ATA Time",
+    "startTime": "Start Time",
+    "endTime": "End Time",
+    "earliestTime": "Earliest Time",
+    "latestTime": "Latest Time",
+    "today": "Today",
+    "current": "Current",
+    "currentMonth": "Current Month",
+    "lastMonth": "Last Month",
+    "thisYear": "This Year",
+    "noStartLimit": "No Start Limit",
+    "noEndLimit": "No End Limit",
+    "startMonth": "Start month",
+    "endMonth": "End month"
+  },
+  "systemSettings": {
+    "title": "System Settings",
+    "profile": "Profile",
+    "personalProfileTab": "Personal Profile",
+    "subscribeNotificationsTab": "Subscribe Notifications",
+    "monitoringSettingsTab": "Monitoring Settings",
+    "notificationEventsForSubscribedShipments": "Notification Events for Subscribed Shipments",
+    "edit": "Edit",
+    "add": "Add",
+    "subscribedShipments": "Subscribed Shipments",
+    "addRule": "Add Rule"
+  },
+ 
+  "dashboard": {
+    "title": "Dashboard",
+    "rememberSaveLayout": "Please remember to click the save button in order to keep the new dashboard layout and widgets.",
+    "save": "Save",
+    "saveFilters": "Save Filters",
+    "saveLayout": "Save Layout",
+    "filters": "Filters",
+    "transportMode": "Transport Mode",
+    "dateRange": "Date Range",
+    "fixed12Months": "The time range is fixed at 12 months.",
+    "salesConfigWarning": "*To ensure the accuracy of the data display, this report needs to be configured and displayed after communicating clearly with Sales.",
+    "kpiReportTip": "KPI Report: Day difference between actual and estimate.",
+    "pendingReportTip": "Pending Report: Showing shipments which are soon to depart/arrive.",
+    "etdToEtaTip": "ETD to ETA (Days): Distribution of Transit Time (ETA-ETD) for All Shipments in Last 12 Months.",
+    "containerCountTip": "Container Count: Total Container Volume by Month (Last 12 Months)",
+    "top10Tip": "Top 10 Origin & Destination: Last 12 Months Shipment Volume Rankings: Top 10 Origin Cities and Top 10 Destination Cities",
+    "co2eTip": "CO2e Emission by Origin or Destination: Last 12 Months CO2e Emission Rankings: Top 10 Origin Cities and Top 10 Destination Cities",
+    "recentStatusTip": "Recent Status: Active shipment list with ETD within the past three months and the next month.",
+    "revenueSpentTip": "Revenue Spent: Based on the billto object, display the corresponding revenue data.",
+    "revenueSpentTitle": "Revenue Spent",
+    "departure": "Departure",
+    "arrival": "Arrival",
+    "satisfactionQuestionWithSpace": "Satisfaction Question ",
+    "shareYourFeedback": "Share your feedback",
+    "feedbackPlaceholder": "Please enter your feedback.",
+    "submitSuccessful": "Submit successfully",
+    "scoringSorryText": "We are so sorry for the inconveniences. We value your experience immensely.",
+    "scoringDissatisfiedTip": "Could you please tell us which aspects of the system you are dissatisfied with?",
+    "scoringNeutralText": "Thank you for sharing your thoughts with us. We value your experience greatly.",
+    "scoringNeutralProposal": "Could you share what aspects you liked and what could be improved?",
+    "scoringSatisfiedText": "Thank you very much for giving us a satisfied rating on our service or system.",
+    "scoringSatisfiedProposal": "We are curious to learn more about what specifically made you feel satisfied.",
+    "highlyDissatisfied": "Highly dissatisfied",
+    "dissatisfied": "Dissatisfied",
+    "neutral": "Neutral",
+    "satisfied": "Satisfied",
+    "highlySatisfied": "Highly satisfied",
+    "satisfactionDetailsQuestion": "Would you like to share more details with us?",
+    "previous": "Previous",
+    "submit": "Submit",
+    "submitAndCommitment": "We are committed to working hard to provide better services.",
+    "apologizeAgain": "Apologize once again for your experience.",
+    "appreciateFeedback": "We greatly appreciate your valuable time and feedback.",
+    "thankYouPositive": "Once again, thank you for your positive evaluation."
+  },
+  "booking": {
+    "title": "Booking",
+    "sendEmail": "Send Email",
+    "search": "Search",
+    "selectDataOnBookingList": "Select data on your booking list",
+    "download": "Download",
+    "downloadWithSelectedColumns": "Download with selected columns",
+    "emailSentSuccessfully": "Email sent successfully",
+    "enterRefNoPlaceholder": "Enter Ref No.",
+    "failedToSendEmail": "Failed to send email",
+    "pleaseEnterEmailContent": "Please enter the email content",
+    "refNoDialogTitle": "Ref No.",
+    "searchPlaceholder": "Enter Booking/HBL/PO/Container/Carrier Booking No. ",
+    "selectReferenceTypePlaceholder": "Select Reference Type",
+    "selected": "Selected",
+    "total": "Total",
+    "transportMode": "Transport Mode",
+    "shipmentStatus": "Shipment Status",
+    "etd": "ETD",
+    "textSearch": "text search",
+    "clearFilters": "Clear Filters",
+    "bookingNo": "Booking No.",
+    "hawbHblNo": "HAWB/HBL No.",
+    "carrierBookingNo": "Carrier Booking No.",
+    "poNo": "PO No.",
+    "refNo": "Ref No.",
+    "vesselAirline": "Vessel / Airline",
+    "voyageFlight": "Voyage / Flight",
+    "incoterm": "Incoterm",
+    "serviceType": "Service Type",
+    "shipper": "Shipper",
+    "consignee": "Consignee",
+    "originAgent": "Origin Agent",
+    "destinationAgent": "Destination Agent",
+    "quantityUnit": "Quantity / Unit",
+    "gWeight": "G. Weight",
+    "chWeight": "Ch. Weight",
+    "volume": "Volume",
+    "marks": "Marks",
+    "description": "Description",
+    "packing": "Packing",
+    "marksAndDescription": "Marks and Description",
+    "bookingListEmptyTip": "We support the following references number to find booking:",
+    "bookingListEmptyTipDetail": "· Booking No./HAWB No./MAWB No./PO No./Carrier Booking No./Contract No./File No./Quote No.",
+    "noResultsFound": "No Results Found",
+    "basicInformation": "Basic Information",
+    "businessPartners": "Business Partners",
+    "containers": "Containers",
+    "origin": "Origin",
+    "destination": "Destination",
+    "etdAtd": "ETD/ATD",
+    "etaAta": "ETA/ATA",
+    "guideSearchAreaTitle": "Frequently Used Search Criteria Display Area",
+    "guideSearchAreaStatus": "Key Booking Status",
+    "guideSearchAreaReferences": "Reference Numbers",
+    "guideSearchAreaTransportMode": "Transport Mode",
+    "guideSearchAreaDateRange": "Date Type & Range",
+    "guideSelectedCriteria": "Selected query criteria display area",
+    "guideClearCriteria": "You can quickly clear selected conditions at this position",
+    "guideMoreFilters": "Click \"More Filters\" to see more search options.",
+    "guideOpenDetail": "Click on the Booking No. or double-click anywhere on a single booking data to enter the detailed page.",
+    "guideDownloadTipLine1": "View the number of shipments selected for download",
+    "guideDownloadTipLine2": "Two download list templates are available",
+    "guideCustomizeColumns": "Drag to right to add columns",
+    "guideCustomizeColumnsLeft": "Drag to left to unselect columns",
+    "guideCustomizeColumnsReorder": "Drag up and down to reorder or select/unselect",
+    "guidePageGuide": "After closing, you can still click the \"Page Guide\" button to view the page guide of the current page.",
+    "guideDashboardIntro": "The Dashboard integrates different types of reports. You can freely select the reports you need.",
+    "guideDashboardFilter": "Each report comes with its own filter options. Simply make your selection and click \"Search\" to refresh the data.",
+    "guideDashboardTooltip": "Hover the icon next to the report name to view the data explanation for each report.",
+    "guideDashboardDrag": "Drag the icon to rearrange the report cards on the dashboard.",
+    "guideDashboardSaveLayout": "Click \"Save Layout\" to preserve your customized report arrangement.",
+    "openInNewTab": "Open in New Tab",
+    "customizeColumnsTip": "Drag item over to this selection or click \"add\" icon to show the column on your booking list",
+    "tdReferenceType": "Reference Type",
+    "tdAction": "Action"
+  },
+  "destinationDelivery": {
+    "title": "Destination Delivery",
+    "configurations": "Configurations",
+    "calendarView": "Calendar View",
+    "listView": "List View",
+    "createNewBooking": "Create New Booking",
+    "truck": "Truck",
+    "rail": "Rail",
+    "totalBookings": "Total Bookings",
+    "pendingApproval": "Pending Approval",
+    "approved": "Approved",
+    "rejected": "Rejected",
+    "cancelled": "Cancelled",
+    "bookingList": "Booking List",
+    "selectDataOnOperationLogList": "Select data on your Operation Log list:",
+    "downloadWithSelectedColumns": "Download with selected columns",
+    "addNewDeliveryAddressTitle": "Add New Delivery Address",
+    "addressLine1Placeholder": "Line 1",
+    "addressLine2Placeholder": "Line 2",
+    "addressLine3Placeholder": "Line 3",
+    "addressLine4Placeholder": "Line 4",
+    "selectCountry": "Select Country",
+    "selectCity": "Select City",
+    "enterPostalCode": "Enter postal code",
+    "contactNamePlaceholder": "Name",
+    "contactMobilePlaceholder": "Mobile Numer",
+    "deliveryDate": "Delivery Date",
+    "deliveryMode": "Delivery Mode",
+    "creationDate": "Creation Date",
+    "searchQuestionPlaceholder": "Search Question Booking No, HBOL No, MBL No, Container No, Consignee",
+    "communication": "Communication",
+    "communicateWithUs": "Communicate with us",
+    "separatedBySemicolon": "Separated by ;",
+    "sendEmail": "Send Email",
+    "pleaseEnterEmailContent": "Please enter the email content",
+    "emailSentSuccessfully": "Email sent successfully",
+    "failedToSendEmail": "Failed to send email",
+    "emptyBookingTitle": "You haven't created any destination delivery bookings yet.",
+    "emptyBookingLine1": "Book truck or rail delivery for your shipments to save time and",
+    "emptyBookingLine2": "ensure smooth last-mile delivery.",
+    "modifyBooking": "Modify Booking",
+    "selected": "Selected",
+    "submit": "Submit",
+    "selectShipments": "Select Shipments",
+    "selectSameConsigneeTip": "Please select items with the same consignee.",
+    "selectSameConsigneeWarning": "Please select same consignee with same delivery information",
+    "searchBookingPlaceholder": "Enter Booking/HBL/PO/Carrier Booking No.",
+    "shipper": "Shipper",
+    "consignee": "Consignee",
+    "requiredFieldsNotEntered": "Required fields not entered.",
+    "outsideRecommendedPeriodForFollowing": "This date for following shipments is outside recommended period.",
+    "outsideRecommendedPeriod": "This date is outside our recommended period.",
+    "eta": "ETA",
+    "ata": "ATA",
+    "recommendedDeliveryDate": "Recommended Delivery Date",
+    "inputVesselName": "Input Vessel Name",
+    "vesselName": "Vessel Name",
+    "deliveryInformation": "Delivery Information",
+    "deliveryAddress": "Delivery Address",
+    "addressBook": "Address Book",
+    "addNewAddress": "Add New Address",
+    "modeType": "Mode Type",
+    "select": "Select",
+    "preferredDeliveryDate": "Preferred Delivery Date",
+    "pleaseSelectDate": "Please Select Date",
+    "deliveryTime": "Delivery Time",
+    "pleaseSelectTime": "Please Select Time",
+    "deliveryReference": "Delivery Reference",
+    "deliveryReferenceTooltip": "Reference to be quoted on arrival at the Warehouse/DC",
+    "specialRequirements": "Special Requirements",
+    "tailLiftRequired": "Tail Lift Required",
+    "sideLoading": "Side Loading",
+    "forkliftRequired": "Forklift Required",
+    "specialEquipment": "Special Equipment",
+    "additionalRequirementsPlaceholder": "Enter any additional requirements or notes...",
+    "modificationReason": "Modification Reason",
+    "createNewRule": "Create New Rule",
+    "completeRequiredFields": "Please complete all required fields.",
+    "unableToSave": "Unable to Save",
+    "setting": "Setting",
+    "selectStationEnableBooking": "Select Station (Enable Booking)",
+    "setBookingWindow": "Set Booking Window",
+    "klnPic": "KLN PIC",
+    "selectEmployeeAccount": "Select Employee Account",
+    "modifyRule": "Modify Rule",
+    "unsavedChanges": "There are unsaved changes.",
+    "confirmLeavePage": "Are you sure you want to leave this page?",
+    "unsavedChangesTitle": "Unsaved Changes",
+    "specificRule": "Specific Rule",
+    "singleDimension": "Single Dimension",
+    "defaultRule": "Default Rule",
+    "noSpecificRecommendedTimeForChoosingDeliveryDate": "No Specific recommended time for choosing delivery date",
+    "recommendDeliveryDate": "Recommend Delivery Date (ETA/ATA)",
+    "etdAtdRuleWindow": "ETD/ATD: {before} days before to {after} days after",
+    "etaAtaRuleWindow": "ETA/ATA: {before} days before to {after} days after",
+    "ok": "OK",
+    "savingSuccess": "Saving successful",
+    "air": "Air",
+    "sea": "Sea",
+    "priority": "Priority",
+    "ruleType": "Rule Type",
+    "port": "Port",
+    "carrier": "Carrier",
+    "fromEtaAtaDays": "From (ETA/ATA + Days)",
+    "toEtaAtaDays": "To (ETA/ATA + Days)",
+    "add": "Add",
+    "configureRegionsAndTimeSlots": "Configure available destination delivery regions and time slots.",
+    "addRule": "Add Rule",
+    "deleteRule": "Delete Rule",
+    "confirmDeleteRule": "Are you sure to delete this notification event?",
+    "configuration": "Configuration",
+    "addedRules": "Added Rules",
+    "failedToLoadOptions": "Failed to load options",
+    "bookings": "Bookings",
+    "accountPasswordExpiredUnavailable": "This account's password has expired and is currently unavailable. Please select a different customer account to continue.",
+    "noTimeRestrictionsForBooking": "No Specific time restrictions for creating booking",
+    "bookingWindowEtdAtd": "Booking Window (ETD/ATD)",
+    "bookingWindowEtaAta": "Booking Window (ETA/ATA)",
+    "revenueSpentTitle": "Revenue Spent",
+    "daysBeforeTo": "days before to",
+    "daysAfter": "days after",
+    "stationList": "Station List",
+    "noData": "No Data",
+    "recommendedDeliveryShipmentsFor": "Recommended Delivery Shipments for {date}",
+    "freeStoragePeriodEnds": "Free Storage Period Ends",
+    "total": "Total",
+    "shipments": "shipments",
+    "totalCartons": "Total Cartons",
+    "packingList": "Packing List",
+    "bookingDetail": "Booking Detail",
+    "confirmRejectBooking": "Are you sure you want to Reject Booking ",
+    "confirmApproveBooking": "Are you sure you want to Approve Booking ",
+    "confirmCancelBooking": "Are you sure you want to Cancel Booking ",
+    "approve": "Approve",
+    "reject": "Reject",
+    "rejectRemarkRequired": "A remark must be filled in for the rejection operation.",
+    "actionSuccessfully": "successfully",
+    "actionFailedTryAgain": "failed, Please try again.",
+    "inputRemarks": "Input remarks",
+    "booking": "Booking",
+    "serviceNotAvailableTitle": "Destination Delivery Service Not Available",
+    "serviceNotAvailableText": "Destination delivery service is not yet available for your shipment destinations. To request this service, please contact the destination office first.",
+    "noEligibleShipmentsTitle": "No Eligible Shipments for Booking",
+    "noEligibleShipmentsText": "Your shipments are currently outside the booking window. Eligible shipments will appear here when booking window opens.",
+    "additionalStorageFeesMayApply": "Additional storage fees may apply.",
+    "additionalFeesNotice": "Additional Fees Notice"
   }
-}
+}

+ 1 - 1
src/views/DestinationDelivery/src/components/TableView/src/TableView.vue

@@ -469,7 +469,7 @@ defineExpose({
           v-for="(item, index) in row[column.field]"
           :key="item.key"
         >
-          <span v-if="index > 0">、</span>
+          <span v-if="(index as number) > 0">、</span>
           <span
             style="color: var(--color-theme); cursor: pointer"
             @click="handleMultLinkClick(item)"

+ 11 - 11
src/views/SystemSettings/src/SystemSettings.vue

@@ -71,25 +71,25 @@ const UnsavedCollapse = () => {
 const AddedRulesColumns = ref([
   {
     field: 'Event',
-    title: 'Event',
+    title: t('systemSettings.event'),
     type: 'normal',
     formatter: ''
   },
   {
     field: 'Event Details',
-    title: 'Event Details',
+    title: t('systemSettings.eventDetails'),
     type: 'normal',
     formatter: ''
   },
   {
     field: 'Frequency',
-    title: 'Frequency',
+    title: t('systemSettings.frequency'),
     type: 'normal',
     formatter: ''
   },
   {
     field: 'Methods',
-    title: 'Methods',
+    title: t('systemSettings.methods'),
     type: 'normal',
     formatter: ''
   }
@@ -97,37 +97,37 @@ const AddedRulesColumns = ref([
 const SubShipmentsColumns = ref([
   {
     field: 'h_bol',
-    title: 'HBOL/HAWB',
+    title: t('systemSettings.hbolHawb'),
     type: 'link',
     formatter: ''
   },
   {
     field: 'shipper',
-    title: 'Shipper',
+    title: t('systemSettings.shipper'),
     type: 'normal',
     formatter: ''
   },
   {
     field: 'consignee',
-    title: 'Consignee',
+    title: t('systemSettings.consignee'),
     type: 'normal',
     formatter: ''
   },
   {
     field: 'etd',
-    title: 'ETD',
+    title: t('systemSettings.etd'),
     type: 'normal',
     formatter: 'date'
   },
   {
     field: 'eta',
-    title: 'ETA',
+    title: t('systemSettings.eta'),
     type: 'normal',
     formatter: 'date'
   },
   {
     field: 'recent_milestone',
-    title: 'Recent Milestone',
+    title: t('systemSettings.recentMilestone'),
     type: 'normal',
     formatter: ''
   }
@@ -149,7 +149,7 @@ const FirstInitSubscribe = () => {
       .FirstInitSubscribe({
         default_time_zone: DefaultTimeZone.value
       })
-      .then((res: any) => {
+      .then(() => {
         getsubscribe()
       })
   } else {

+ 18 - 13
src/views/SystemSettings/src/components/CreateNewrule/src/CreateNewrule.vue

@@ -57,7 +57,12 @@ onMounted(() => {
   <div class="Title">
     <div>{{ t('systemSettings.createNewRule') }}</div>
     <div>
-      <el-button class="create_button" style="margin-right: 8px;" type="default" @click="CancelRulesVisible = true">
+      <el-button
+        class="create_button"
+        style="margin-right: 8px"
+        type="default"
+        @click="CancelRulesVisible = true"
+      >
         <span class="iconfont_icon">
           <svg class="iconfont" aria-hidden="true">
             <use xlink:href="#icon-icon_return_b"></use>
@@ -71,9 +76,9 @@ onMounted(() => {
         <div style="font-weight: 400">{{ t('systemSettings.confirmLeavePage') }}</div>
         <template #footer>
           <div class="dialog-footer">
-            <el-button type="default" @click="CancelRulesVisible = false" style="width: 100px"
-              >{{ t('common.cancel') }}</el-button
-            >
+            <el-button type="default" @click="CancelRulesVisible = false" style="width: 100px">{{
+              t('common.cancel')
+            }}</el-button>
             <el-button class="el-button--warning" @click="router.back()" style="width: 100px">
               OK
             </el-button>
@@ -92,19 +97,19 @@ onMounted(() => {
       </el-dialog>
       <!-- 切换select -->
       <el-dialog v-model="ChangeRulesVisible" width="480">
-        <div style="font-weight: 400">You have unsaved changes.</div>
-        <div style="font-weight: 400">Are you sure you want to leave this page?</div>
+        <div style="font-weight: 400">{{ t('systemSettings.unsavedChanges') }}</div>
+        <div style="font-weight: 400">{{ t('systemSettings.confirmLeavePage') }}</div>
         <template #footer>
           <div class="dialog-footer">
-            <el-button type="default" @click="ChangeRulesVisible = false" style="width: 100px"
-              >Cancel</el-button
-            >
+            <el-button type="default" @click="ChangeRulesVisible = false" style="width: 100px">{{
+              t('common.cancel')
+            }}</el-button>
             <el-button
               class="el-button--warning"
               @click="ChangeRulesVisibleOK"
               style="width: 100px"
             >
-              OK
+              {{ t('common.ok') }}
             </el-button>
           </div>
         </template>
@@ -115,7 +120,7 @@ onMounted(() => {
                 <use xlink:href="#icon-icon_tipsfilled_b"></use>
               </svg>
             </span>
-            Unsaved Changes
+            {{ t('systemSettings.unsavedChangesTitle') }}
           </div>
         </template>
       </el-dialog>
@@ -157,7 +162,7 @@ onMounted(() => {
       <TableEmpty
         v-if="notificationvalue == '' || notificationvalue == undefined"
         style="margin-top: 100px"
-        EmptyTitle="{{ t('systemSettings.pleaseSelectNotificationEventsFirst') }}"
+        :EmptyTitle="t('systemSettings.pleaseSelectNotificationEventsFirst')"
       ></TableEmpty>
       <div v-else>
         <CreateAddRules ref="CreateAddRulesRef" :TitleType="notificationvalue"></CreateAddRules>
@@ -266,4 +271,4 @@ onMounted(() => {
 :deep(footer.el-dialog__footer) {
   border-top: none;
 }
-</style>
+</style>

+ 1 - 1
src/views/SystemSettings/src/components/MonitoringTable/src/MonitoringTable.vue

@@ -191,7 +191,7 @@ onMounted(() => {
     >
       <!-- 空数据时的插槽 -->
       <template #empty v-if="tableData.data.length === 0">
-        <TableEmpty EmptyTitle="{{ t('systemSettings.customizeYourShipmentTrackingPreferences') }}">
+        <TableEmpty :EmptyTitle="t('systemSettings.customizeYourShipmentTrackingPreferences')">
           <template #suggestion>
             <el-button class="el-button--main" @click="ToCreateRule"
               >+ {{ t('systemSettings.addRule') }}</el-button

+ 1 - 1
src/views/SystemSettings/src/components/SettingTable/src/SettingTable.vue

@@ -176,7 +176,7 @@ const getpaginationTableData = () => {
               t('common.cancel')
             }}</el-button>
             <el-button style="width: 100px" type="warning" @click="handleDelete(row)">
-              OK
+              {{ t('common.ok') }}
             </el-button>
           </div>
           <template #reference>

+ 16 - 16
src/views/TemplateManagement/src/components/CreateReportTemplate/src/CreateReportTemplate.vue

@@ -141,15 +141,15 @@ const changeOldLevel = (val: string) => {
 const handlePageSave = () => {
   let verified = true
   if (!infoData.value.reportName.trim()) {
-    ElMessage.warning(t('templateManagement.createReportTemplate.reportNameRequired'))
+    ElMessage.warning(t('templateManagement.reportNameRequired'))
     verified = false
   }
   if (!infoData.value.reportLevel) {
-    ElMessage.warning(t('templateManagement.createReportTemplate.reportLevelRequired'))
+    ElMessage.warning(t('templateManagement.reportLevelRequired'))
     verified = false
   }
   if (!infoData.value.reportDescription.trim()) {
-    ElMessage.warning(t('templateManagement.createReportTemplate.reportDescriptionRequired'))
+    ElMessage.warning(t('templateManagement.reportDescriptionRequired'))
     verified = false
   }
   if (
@@ -159,7 +159,7 @@ const handlePageSave = () => {
     !specificRoles.value.systemAccount?.length
   ) {
     ElMessage.warning(
-      t('templateManagement.createReportTemplate.specificRolesRequired')
+      t('templateManagement.specificRolesRequired')
     )
     verified = false
   }
@@ -213,13 +213,13 @@ const handlePageSave = () => {
     </div>
     <div class="display">
       <div class="basic-info template-box">
-        <div class="header">{{ t('templateManagement.createReportTemplate.basicReportInformation') }}</div>
+        <div class="header">{{ t('templateManagement.basicReportInformation') }}</div>
         <div class="content-box">
           <div class="info-item" style="display: flex; gap: 8px">
             <div class="report-name" style="flex: 1">
               <div class="label">
                 <span style="color: var(--color-danger)">*</span>
-                <span>{{ t('templateManagement.createReportTemplate.reportNameLabel') }}</span>
+                <span>{{ t('templateManagement.reportNameLabel') }}</span>
               </div>
               <el-input
                 v-model="infoData.reportName"
@@ -229,7 +229,7 @@ const handlePageSave = () => {
             <div class="report-level" style="flex: 1">
               <div class="label">
                 <span style="color: var(--color-danger)">*</span>
-                <span>{{ t('templateManagement.createReportTemplate.reportLevelLabel') }}</span>
+                <span>{{ t('templateManagement.reportLevelLabel') }}</span>
               </div>
               <el-select
                 v-model="infoData.reportLevel"
@@ -248,7 +248,7 @@ const handlePageSave = () => {
           <div class="info-item">
             <div class="label">
               <span style="color: var(--color-danger)">*</span>
-              <span>{{ t('templateManagement.createReportTemplate.reportDescriptionLabel') }}</span>
+              <span>{{ t('templateManagement.reportDescriptionLabel') }}</span>
             </div>
             <el-input
               type="textarea"
@@ -266,7 +266,7 @@ const handlePageSave = () => {
         ref="fieldsConfigurationRef"
       ></ReportFieldsConfiguration>
       <div class="report-access-control template-box">
-        <div class="header">{{ t('templateManagement.createReportTemplate.reportAccessControl') }}</div>
+        <div class="header">{{ t('templateManagement.reportAccessControl') }}</div>
         <div class="content-box">
           <el-radio-group
             class="radio-group"
@@ -276,9 +276,9 @@ const handlePageSave = () => {
             <el-radio class="radio-item" value="All Users">
               <template #default>
                 <div class="radio-content">
-                  <p class="label">{{ t('templateManagement.createReportTemplate.allUsers') }}</p>
+                  <p class="label">{{ t('templateManagement.allUsers') }}</p>
                   <p class="description">
-                    {{ t('templateManagement.createReportTemplate.allUsersDescription') }}
+                    {{ t('templateManagement.allUsersDescription') }}
                   </p>
                 </div>
               </template>
@@ -287,8 +287,8 @@ const handlePageSave = () => {
               <template #default>
                 <div class="radio-content">
                   <div class="top-options">
-                    <p class="label">{{ t('templateManagement.createReportTemplate.specificRoles') }}</p>
-                    <p class="description">{{ t('templateManagement.createReportTemplate.specificRolesDescription') }}</p>
+                    <p class="label">{{ t('templateManagement.specificRoles') }}</p>
+                    <p class="description">{{ t('templateManagement.specificRolesDescription') }}</p>
                   </div>
                   <div
                     class="extended-filter"
@@ -299,7 +299,7 @@ const handlePageSave = () => {
                     <div class="filter-item" style="margin-bottom: 16px">
                       <div class="label">
                         <span style="color: var(--color-danger)">*</span>
-                        <span>{{ t('templateManagement.createReportTemplate.partyId') }}</span>
+                        <span>{{ t('templateManagement.partyId') }}</span>
                       </div>
                       <partyIDSelect
                         @change-data="changePartyId"
@@ -309,7 +309,7 @@ const handlePageSave = () => {
                     <div class="filter-item" style="margin-bottom: 16px">
                       <div class="label">
                         <span style="color: var(--color-danger)">*</span>
-                        <span>{{ t('templateManagement.createReportTemplate.groupName') }}</span>
+                        <span>{{ t('templateManagement.groupName') }}</span>
                       </div>
                       <GroupNameSelect
                         @change-data="changeGroupName"
@@ -319,7 +319,7 @@ const handlePageSave = () => {
                     <div class="filter-item">
                       <div class="label">
                         <span style="color: var(--color-danger)">*</span>
-                        <span>{{ t('templateManagement.createReportTemplate.klnOnlineAccount') }}</span>
+                        <span>{{ t('templateManagement.klnOnlineAccount') }}</span>
                       </div>
                       <AccountSelect
                         @change-data="changeAccount"

+ 21 - 21
src/views/TemplateManagement/src/components/CreateReportTemplate/src/components/ReportFieldsConfiguration.vue

@@ -115,12 +115,12 @@ const handleFieldTypeChange = () => {
 }
 const addNewField = () => {
   if (!newFieldInfo.value.name?.trim()) {
-    ElMessage.warning(t('templateManagement.reportFieldsConfiguration.newFieldNameRequired'))
+    ElMessage.warning(t('templateManagement.newFieldNameRequired'))
     return
   }
 
   if (newFieldInfo.value.fieldType === 'Fixed Value' && !newFieldInfo.value.value?.trim()) {
-    ElMessage.warning(t('templateManagement.reportFieldsConfiguration.fixedValueRequired'))
+    ElMessage.warning(t('templateManagement.fixedValueRequired'))
     return
   }
   fieldsList.value.unshift({
@@ -161,7 +161,7 @@ const AdjustmentFieldRef = ref()
 // 打开定制表格弹窗
 const handleCustomizeColumns = () => {
   if (!props.reportLevel) {
-    ElMessage.warning(t('templateManagement.reportFieldsConfiguration.reportLevelRequired'))
+    ElMessage.warning(t('templateManagement.reportLevelRequired'))
     return
   }
   const params = {
@@ -307,7 +307,7 @@ defineExpose({
 <template>
   <div class="fields-configuration template-box">
     <div class="header">
-      <span>Report Fields Configuration</span>
+      <span>{{ t('templateManagement.reportFieldsConfigurationTitle') }}</span>
 
       <div class="right-option">
         <el-button
@@ -316,7 +316,7 @@ defineExpose({
           style="width: 148px; padding-top: 11px"
         >
           <span style="margin-right: 3px" class="font_family icon-icon_add_b"></span>
-          <span>Add New Field</span>
+          <span>{{ t('templateManagement.addNewField') }}</span>
         </el-button>
         <el-button
           v-if="fieldsList.length > 0"
@@ -325,16 +325,16 @@ defineExpose({
           style="width: 110px; padding-top: 11px"
         >
           <span style="margin-right: 3px" class="font_family icon-icon_add_b"></span>
-          <span>Select Field</span>
+          <span>{{ t('templateManagement.selectField') }}</span>
         </el-button>
       </div>
     </div>
     <div class="content-box">
       <div class="empty-box" v-if="fieldsList.length === 0">
         <el-button class="el-button--dark" @click="handleCustomizeColumns">
-          <span class="font_family icon-icon_add_b"></span>Add/Edit Field
+          <span class="font_family icon-icon_add_b"></span>{{ t('templateManagement.addEditField') }}
         </el-button>
-        <p>No field selected. click “Add Field” to get started.</p>
+        <p>{{ t('templateManagement.noFieldSelectedTip') }}</p>
       </div>
       <div class="fields-list" v-else>
         <VueDraggable
@@ -366,7 +366,7 @@ defineExpose({
               :name="fieldItem.uniqueId"
               class="display-name"
               v-model="fieldItem.displayName"
-              :placeholder="t('report.displayNameInReport')"
+              :placeholder="t('templateManagement.displayNameInReport')"
             ></el-input>
             <div class="actions">
               <div class="checkbox-group">
@@ -378,13 +378,13 @@ defineExpose({
                   "
                   v-model="fieldItem.isFilter"
                   @change="changeFieldConfig($event, fieldItem.field, index, 'isFilter')"
-                  >{{ t('templateManagement.createReportTemplate.filter') }}</el-checkbox
+                  >{{ t('templateManagement.filter') }}</el-checkbox
                 >
                 <el-checkbox
                   :disabled="fieldItem.fieldType !== 'System'"
                   v-model="fieldItem.isSort"
                   @change="changeFieldConfig($event, fieldItem.field, index, 'isSort')"
-                  >{{ t('templateManagement.createReportTemplate.sort') }}</el-checkbox
+                  >{{ t('templateManagement.sort') }}</el-checkbox
                 >
               </div>
               <div class="action-icon">
@@ -416,7 +416,7 @@ defineExpose({
   <AdjustmentField @apply="handleApplay" ref="AdjustmentFieldRef" />
   <el-dialog
     class="add-new-field-dialog"
-    :title="t('templateManagement.createReportTemplate.addNewFieldTitle')"
+    :title="t('templateManagement.addNewFieldTitle')"
     v-model="addNewFieldVisible"
     @closed="clearNewFieldData"
     width="480"
@@ -425,24 +425,24 @@ defineExpose({
       <div class="field-item">
         <div class="label">
           <span class="required-symbol">*</span>
-          <span>{{ t('templateManagement.createReportTemplate.newFieldNameLabel') }}</span>
+          <span>{{ t('templateManagement.newFieldNameLabel') }}</span>
         </div>
         <el-input :placeholder="t('report.pleaseEnter')" v-model="newFieldInfo.name"></el-input>
       </div>
       <div class="field-item field-value">
         <div class="label">
           <span class="required-symbol">*</span>
-          <span>{{ t('templateManagement.createReportTemplate.fieldValueLabel') }}</span>
+          <span>{{ t('templateManagement.fieldValueLabel') }}</span>
         </div>
         <el-radio-group v-model="newFieldInfo.fieldType" @change="handleFieldTypeChange">
-          <el-radio label="Blank">{{ t('templateManagement.createReportTemplate.blankText') }}</el-radio>
-          <el-radio label="Fixed Value">{{ t('templateManagement.createReportTemplate.fixedValueText') }}</el-radio>
+          <el-radio label="Blank">{{ t('templateManagement.blankText') }}</el-radio>
+          <el-radio label="Fixed Value">{{ t('templateManagement.fixedValueText') }}</el-radio>
         </el-radio-group>
       </div>
       <div class="field-item" v-if="newFieldInfo.fieldType === 'Fixed Value'">
         <div class="label">
           <span class="required-symbol">*</span>
-          <span>{{ t('templateManagement.createReportTemplate.fixedValueLabel') }}</span>
+          <span>{{ t('templateManagement.fixedValueLabel') }}</span>
         </div>
         <el-input :placeholder="t('report.pleaseEnter')" v-model="newFieldInfo.value"></el-input>
       </div>
@@ -463,7 +463,7 @@ defineExpose({
   <el-dialog
     class="field-mapping-dialog"
     v-model="fieldMappingVisible"
-    :title="t('templateManagement.createReportTemplate.mappingTitle')"
+    :title="t('templateManagement.mappingTitle')"
     width="800"
     @close="clearMappingData"
   >
@@ -472,11 +472,11 @@ defineExpose({
         <div class="label">
           <div class="left-label">
             <span style="color: var(--color-danger)">*</span>
-              <span>{{ t('templateManagement.createReportTemplate.systemValueLabel') }}</span>
+              <span>{{ t('templateManagement.systemValueLabel') }}</span>
           </div>
           <div class="right-label">
             <span style="color: var(--color-danger)">*</span>
-            <span>{{ t('templateManagement.createReportTemplate.outputValueLabel') }}</span>
+            <span>{{ t('templateManagement.outputValueLabel') }}</span>
           </div>
         </div>
         <div style="max-height: 380px; overflow-y: auto">
@@ -503,7 +503,7 @@ defineExpose({
       style="height: 32px; margin-top: 8px; padding: 8px"
     >
       <span class="font_family icon-icon_add_b" style="color: var(--color-theme)"></span>
-      <span style="color: var(--color-theme)">{{ t('templateManagement.createReportTemplate.addMapping') }}</span>
+      <span style="color: var(--color-theme)">{{ t('templateManagement.addMapping') }}</span>
     </el-button>
     <template #footer>
       <el-button

+ 5 - 5
src/views/Tracking/src/components/PublicTracking/src/components/BasicInformation.vue

@@ -136,19 +136,19 @@ const convertData = (data: any) => {
     ],
     packing: [
       {
-        label: 'Quantity / Unit',
+        labelKey: 'ptQuantityUnit',
         content: data.packing['Quantity/Unit'] || '--'
       },
       {
-        label: 'G. Weight',
+        labelKey: 'ptGWeight',
         content: substringFromStart(data.packing['G. Weight'], -4) + ' KGS'
       },
       {
-        label: 'Ch. Weight',
+        labelKey: 'ptChWeight',
         content: substringFromStart(data.packing['Ch. Weight'], -4) + ' KGS'
       },
       {
-        label: 'Volume',
+        labelKey: 'ptVolume',
         content: substringFromStart(data.packing['Volume'], -4) + ' CBM'
       }
     ]
@@ -224,7 +224,7 @@ const handleCopy = (data: any) => {
         </div>
       </div>
       <div class="packing">
-        <div class="header">Packing</div>
+        <div class="header">{{ t('tracking.packing') }}</div>
         <div class="content">
           <div class="data-item" v-for="item in allData.packing" :key="item.labelKey">
             <div class="title">{{ t(`tracking.${item.labelKey}`) }}</div>

+ 9 - 9
src/views/Tracking/src/components/PublicTracking/src/components/PublicTrackingDetail.vue

@@ -83,7 +83,7 @@ const openShareDialog = () => {
   <div class="tracking-detail">
     <!-- 分享链接 -->
     <div class="share-link" @click="openShareDialog">
-      <el-tooltip content="Share" :offset="4">
+      <el-tooltip :content="t('tracking.share')" :offset="4">
         <span class="font_family icon-icon_share_b share-icon"></span>
       </el-tooltip>
     </div>
@@ -94,7 +94,7 @@ const openShareDialog = () => {
           :class="[`icon-${transportationMode?.[allData?.transportInfo?.mode]}`]"
           style="font-size: 64px"
         ></span>
-        <div class="no">House No. {{ allData?.transportInfo['Tracking No.'] }}</div>
+        <div class="no">{{ t('tracking.houseNo') }} {{ allData?.transportInfo['Tracking No.'] }}</div>
         <VTag large :type="allData?.transportInfo?.status">{{
           allData?.transportInfo?.status
         }}</VTag>
@@ -102,7 +102,7 @@ const openShareDialog = () => {
       <div class="detail-info">
         <div class="item transport-way">
           <div class="origin">
-            <div class="title">Origin</div>
+            <div class="title">{{ t('tracking.origin') }}</div>
             <div class="content">
               <el-tooltip v-if="isOriginOverflow" placement="top">
                 <template #content>{{ allData?.transportInfo?.origin || '--' }}</template>
@@ -120,7 +120,7 @@ const openShareDialog = () => {
             </div>
           </div>
           <div class="destination">
-            <div class="title">Destination</div>
+            <div class="title">{{ t('tracking.destination') }}</div>
             <div class="content">
               <el-tooltip v-if="isDestinationOverflow" placement="top">
                 <template #content>{{ allData?.transportInfo?.destination || '--' }}</template>
@@ -135,7 +135,7 @@ const openShareDialog = () => {
           </div>
         </div>
         <div class="item">
-          <div class="title">ETD/ATD</div>
+          <div class="title">{{ t('tracking.etdAtd') }}</div>
           <div class="content">
             <span
               >{{
@@ -149,7 +149,7 @@ const openShareDialog = () => {
           </div>
         </div>
         <div class="item">
-          <div class="title">ETA/ATA</div>
+          <div class="title">{{ t('tracking.etaAta') }}</div>
           <div class="content">
             <span
               >{{
@@ -169,9 +169,9 @@ const openShareDialog = () => {
         <template #header>
           <div style="display: flex; border-radius: 12px 12px 0 0">
             <div class="basic-information-header">
-              <span>Basic Information</span>
+              <span>{{ t('tracking.basicInformation') }}</span>
             </div>
-            <div style="padding-left: 16px">Business Partners</div>
+            <div style="padding-left: 16px">{{ t('tracking.businessPartners') }}</div>
           </div>
         </template>
         <template #content>
@@ -180,7 +180,7 @@ const openShareDialog = () => {
       </VBox>
       <!-- Milestones -->
       <VBox style="margin-top: 8px" :isSeeAll="false" :is-draggable="false">
-        <template #header>Milestones</template>
+        <template #header>{{ t('tracking.milestones') }}</template>
         <template #content>
           <MilestonesTable :data="allData"></MilestonesTable>
         </template>

+ 3 - 3
src/views/Tracking/src/components/PublicTracking/src/components/ShareLinkDialog.vue

@@ -19,7 +19,7 @@ const copied = ref(false)
 const copyToClipboard = async () => {
   try {
     // 使用 navigator.clipboard.writeText() 复制文本
-    await navigator.clipboard.writeText(tracking.value)
+    await navigator.clipboard.writeText(shareLink.value)
     ElMessage.success(t('tracking.copiedToClipboard'))
     // 设置已复制标志
     copied.value = true
@@ -47,7 +47,7 @@ const copyToClipboard = async () => {
         <img src="../images/share-link.png" />
       </div>
       <div class="tips">
-        <span>Copy the link to share this shipment with anyone.</span>
+        <span>{{ t('tracking.shareLinkTip') }}</span>
       </div>
       <div class="link">
         <span>{{ shareLink }}</span>
@@ -60,7 +60,7 @@ const copyToClipboard = async () => {
         @click="copyToClipboard"
       >
         <span class="font_family icon-icon_text_links_b"></span>
-        <span style="margin-left: 4px">Copy Link</span>
+        <span style="margin-left: 4px">{{ t('tracking.copyLink') }}</span>
       </el-button>
     </template>
   </el-dialog>

+ 4 - 4
src/views/Tracking/src/components/TrackingDetail/src/components/AddReferenceDialog.vue

@@ -26,20 +26,20 @@ const tableData = ref<VxeGridProps<any>>({
   minHeight: 100,
   columns: [
     {
-      title: t('tracking.tdReferenceType'),
+      title: t('tracking.referenceType'),
       field: 'referenceType',
       width: 250,
       editRender: { enabled: true },
       slots: { edit: 'refType' }
     },
     {
-      title: t('tracking.tdRefNo'),
+      title: t('tracking.refNo'),
       field: 'refNo',
       editRender: { enabled: true },
       slots: { edit: 'refNo' }
     },
     {
-      title: t('tracking.tdAction'),
+      title: t('common.action'),
       width: 90,
       fixed: 'left',
       slots: { default: 'action' }
@@ -109,7 +109,7 @@ defineExpose({
     <div>
       <el-button style="margin-bottom: 8px" class="el-button-text" @click="addNewReference">
         <span class="font_family icon-icon_add_b"></span>
-        {{ t('tracking.tdAddReference') }}
+        {{ t('tracking.addReference') }}
       </el-button>
       <vxe-grid ref="tableRef" v-bind="tableData">
         <!-- action操作栏的插槽 -->

+ 1 - 1
src/views/Tracking/src/components/TrackingDetail/src/components/AttachmentView.vue

@@ -61,7 +61,7 @@ watch(
       tableData.value.columns = [
         ...handleColumns(attachment.document_column),
         {
-          title: 'Action',
+          title: t('common.action'),
           width: 90,
           fixed: 'left',
           slots: { default: 'action' }

+ 6 - 3
src/views/Tracking/src/components/TrackingDetail/src/components/ContainersView.vue

@@ -1,9 +1,12 @@
 <script setup lang="ts">
 import { type VxeGridInstance, type VxeGridProps } from 'vxe-table'
+import { useI18n } from 'vue-i18n'
 // import { autoWidth } from '@/utils/table'
 import { useRowClickStyle } from '@/hooks/rowClickStyle'
 import { formatTimezone, formatNumber } from '@/utils/tools'
 
+const { t } = useI18n()
+
 const props = defineProps({
   data: Object
 })
@@ -104,11 +107,11 @@ useRowClickStyle(tableRef)
                   <div class="date value-color">{{ formatTimezone(item.date, item.timezone) }}</div>
                 </div>
                 <div class="center-code">
-                  <span>Location Code: </span>
+                  <span>{{ t('tracking.locationCode') }}: </span>
                   <span class="value-color">{{ item.code }}</span>
                 </div>
                 <div class="right-city">
-                  <span>Location City: </span>
+                  <span>{{ t('tracking.locationCity') }}: </span>
                   <span class="value-color">{{ item.uncity }}</span>
                 </div>
               </div>
@@ -118,7 +121,7 @@ useRowClickStyle(tableRef)
         </div>
       </template>
       <template #empty>
-        <div class="empty">No data</div>
+        <div class="empty">{{ t('common.noData') }}</div>
       </template>
     </vxe-grid>
   </div>

+ 3 - 3
src/views/Tracking/src/components/TrackingDetail/src/components/EmailDrawer.vue

@@ -171,7 +171,7 @@ const sendEmail = () => {
   <div class="email-view">
     <div class="email-path">
       <span class="font_family icon-icon_email_b" style="font-size: 18px"></span>
-      <span class="label">Communication to KLN: &nbsp;</span>
+      <span class="label">{{ t('tracking.communicationToKln') }} &nbsp;</span>
       <span class="content">{{ emailData.email }}</span>
     </div>
     <div class="separated-by">
@@ -185,11 +185,11 @@ const sendEmail = () => {
               cursor: default;
             "
           >
-            <span style="font-weight: 600">CC:</span>
+            <span style="font-weight: 600">{{ t('tracking.cc') }}:</span>
             <el-tooltip
               class="box-item"
               effect="dark"
-              content="Separated by;"
+              :content="t('tracking.separatedByTip')"
               placement="top-start"
               :offset="-8"
             >

+ 4 - 1
src/views/Tracking/src/components/TrackingDetail/src/components/MilestonesTable.vue

@@ -1,9 +1,12 @@
 <script setup lang="ts">
 import { type VxeGridInstance, type VxeGridProps } from 'vxe-table'
+import { useI18n } from 'vue-i18n'
 // import { autoWidth } from '@/utils/table'
 import { useRowClickStyle } from '@/hooks/rowClickStyle'
 import { formatTimezone } from '@/utils/tools'
 
+const { t } = useI18n()
+
 const props = defineProps({
   data: Object
 })
@@ -78,7 +81,7 @@ useRowClickStyle(tableRef)
   <div class="Milestones">
     <vxe-grid class="radius-bottom" ref="tableRef" :style="{ border: 'none' }" v-bind="tableData">
       <template #empty>
-        <div class="empty">No data</div>
+        <div class="empty">{{ t('common.noData') }}</div>
       </template>
     </vxe-grid>
   </div>

+ 11 - 6
src/views/Tracking/src/components/TrackingDetail/src/components/RoutesView.vue

@@ -3,6 +3,9 @@ import { transportationMode } from '@/components/transportationMode'
 import { useOverflow } from '@/hooks/useOverflow'
 import { formatTimezone } from '@/utils/tools'
 
+import { useI18n } from 'vue-i18n'
+
+const { t } = useI18n()
 const props = defineProps({
   data: Object
 })
@@ -63,18 +66,20 @@ const { isOverflow: isDetailDestinationOverflow } = useOverflow(detailDestinatio
 
 <template>
   <div class="routes-view">
-    <div class="title">Total number of legs: {{ routes.length }}</div>
+    <div class="title">{{ t('tracking.legsCount', { count: routes.length }) }}</div>
     <div class="routes">
       <div class="route-item" v-for="(item, index) in routes" :key="item.serialNumber">
         <div class="basic-info" @click="item.isCollapse = !item.isCollapse">
-          <div class="serial-number border-right">Leg {{ index + 1 }}</div>
+          <div class="serial-number border-right">
+            {{ t('tracking.leg', { count: (index as number) + 1 }) }}
+          </div>
           <div class="mode border-right">
             <span class="font_family" :class="[`icon-${transportationMode?.[item.mode]}`]"></span>
             {{ item.mode_label }}
           </div>
           <div class="place border-right">
             <div class="origin">
-              <div class="title">Origin</div>
+              <div class="title">{{ t('tracking.origin') }}</div>
               <div class="content">
                 <el-tooltip v-if="isBasicOriginOverflow?.[index]" placement="top">
                   <template #content>{{ item.origin || '--' }}</template>
@@ -93,7 +98,7 @@ const { isOverflow: isDetailDestinationOverflow } = useOverflow(detailDestinatio
               </div>
             </div>
             <div class="destination" ref="">
-              <div class="title">Destination</div>
+              <div class="title">{{ t('tracking.destination') }}</div>
               <el-tooltip v-if="isBasicDestinationOverflow?.[index]" placement="top">
                 <template #content>{{ item.destination || '--' }}</template>
                 <span ref="basicDestinationRef" class="content single-line-ellipsis">{{
@@ -180,11 +185,11 @@ const { isOverflow: isDetailDestinationOverflow } = useOverflow(detailDestinatio
           </div>
           <div class="transport-info">
             <div class="item">
-              <div class="title">Vessel / Airline</div>
+              <div class="title">{{ t('tracking.vesselAirline') }}</div>
               <div class="content">{{ item.vessel || '--' }}</div>
             </div>
             <div class="item">
-              <div class="title">Voyage / Flight</div>
+              <div class="title">{{ t('tracking.voyageFlight') }}</div>
               <div class="content">{{ item.voyageNo || '--' }}</div>
             </div>
           </div>