From 80c052f101c1b678e55a96b0e9058f9038471182 Mon Sep 17 00:00:00 2001 From: jingyang <72259332+zjy365@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:47:01 +0800 Subject: [PATCH] refactor: improve i18n in dbprovider for better developer experience (#4919) * refactor: improve i18n in dbprovider for better developer experience Signed-off-by: jingyang <3161362058@qq.com> * delete unuserd keys * update keys * update * update * update quota --------- Signed-off-by: jingyang <3161362058@qq.com> --- frontend/providers/dbprovider/.gitignore | 2 +- .../dbprovider/.vscode/settings.json | 19 + .../dbprovider/next-i18next.config.js | 5 +- .../dbprovider/public/locales/en/common.json | 440 +++++++++-------- .../dbprovider/public/locales/zh/common.json | 441 +++++++++--------- .../src/components/DBStatusTag/index.tsx | 6 +- .../src/components/FileSelect/index.tsx | 4 +- .../src/components/PriceBox/index.tsx | 17 +- .../src/components/QuotaBox/index.tsx | 2 +- .../src/components/Textarea/TagTextarea.tsx | 2 +- .../dbprovider/src/components/Tip/index.tsx | 3 +- .../dbprovider/src/constants/backup.ts | 13 +- .../dbprovider/src/constants/editApp.ts | 26 +- .../dbprovider/src/hooks/useConfirm.tsx | 13 +- .../providers/dbprovider/src/mock/apps.ts | 135 ------ .../providers/dbprovider/src/pages/_app.tsx | 4 +- .../db/detail/components/AppBaseInfo.tsx | 47 +- .../db/detail/components/BackupModal.tsx | 45 +- .../db/detail/components/BackupTable.tsx | 17 +- .../pages/db/detail/components/DelModal.tsx | 26 +- .../db/detail/components/DumpImport/index.tsx | 34 +- .../src/pages/db/detail/components/Header.tsx | 23 +- .../db/detail/components/Migrate/Table.tsx | 11 +- .../components/Monitor/ChartTemplate.tsx | 2 +- .../detail/components/Monitor/RunningTime.tsx | 10 +- .../db/detail/components/Monitor/index.tsx | 48 +- .../db/detail/components/PodDetailModal.tsx | 7 +- .../src/pages/db/detail/components/Pods.tsx | 13 +- .../db/detail/components/RestoreModal.tsx | 10 +- .../dbprovider/src/pages/db/detail/index.tsx | 13 +- .../src/pages/db/edit/components/Form.tsx | 47 +- .../src/pages/db/edit/components/Header.tsx | 5 +- .../src/pages/db/edit/components/Yaml.tsx | 4 +- .../dbprovider/src/pages/db/edit/index.tsx | 2 +- .../src/pages/db/migrate/components/Form.tsx | 53 +-- .../pages/db/migrate/components/Header.tsx | 5 +- .../pages/db/migrate/components/Prepare.tsx | 14 +- .../src/pages/db/migrate/components/Yaml.tsx | 4 +- .../dbprovider/src/pages/db/migrate/index.tsx | 12 +- .../src/pages/dbs/components/dbList.tsx | 30 +- .../src/pages/dbs/components/empty.tsx | 4 +- .../providers/dbprovider/src/store/user.ts | 15 +- .../dbprovider/src/types/i18next.d.ts | 32 ++ .../dbprovider/src/types/monitor.d.ts | 4 +- .../providers/dbprovider/src/utils/tools.ts | 9 +- 45 files changed, 796 insertions(+), 882 deletions(-) create mode 100644 frontend/providers/dbprovider/.vscode/settings.json delete mode 100644 frontend/providers/dbprovider/src/mock/apps.ts create mode 100644 frontend/providers/dbprovider/src/types/i18next.d.ts diff --git a/frontend/providers/dbprovider/.gitignore b/frontend/providers/dbprovider/.gitignore index dc5af0406b4..289a3f0b6e1 100644 --- a/frontend/providers/dbprovider/.gitignore +++ b/frontend/providers/dbprovider/.gitignore @@ -35,7 +35,7 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts /public/trainData/ -/.vscode/ +/local/ platform.json .yalc/ yalc.lock diff --git a/frontend/providers/dbprovider/.vscode/settings.json b/frontend/providers/dbprovider/.vscode/settings.json new file mode 100644 index 00000000000..d386c478d87 --- /dev/null +++ b/frontend/providers/dbprovider/.vscode/settings.json @@ -0,0 +1,19 @@ +{ + "i18n-ally.localesPaths": [ + "public/locales" + ], + "i18n-ally.enabledParsers": [ + "json", + "yaml", + "js", + "ts" + ], + "i18n-ally.keystyle": "nested", + "i18n-ally.sortKeys": true, + "i18n-ally.keepFulfilled": false, + "i18n-ally.sourceLanguage": "zh", + "i18n-ally.displayLanguage": "zh", + // "i18n-ally.namespace": true, + "i18n-ally.pathMatcher": "{locale}/{namespaces}.json", + "i18n-ally.extract.targetPickingStrategy": "most-similar-by-key" +} \ No newline at end of file diff --git a/frontend/providers/dbprovider/next-i18next.config.js b/frontend/providers/dbprovider/next-i18next.config.js index 8dca5135fe0..0e139df71ab 100644 --- a/frontend/providers/dbprovider/next-i18next.config.js +++ b/frontend/providers/dbprovider/next-i18next.config.js @@ -8,5 +8,6 @@ module.exports = { defaultLocale: 'zh', locales: ['en', 'zh'], localeDetection: false - } -}; + }, + reloadOnPrerender: process.env.NODE_ENV === 'development' +} diff --git a/frontend/providers/dbprovider/public/locales/en/common.json b/frontend/providers/dbprovider/public/locales/en/common.json index 44a805c3d80..ed4ea163fce 100644 --- a/frontend/providers/dbprovider/public/locales/en/common.json +++ b/frontend/providers/dbprovider/public/locales/en/common.json @@ -1,282 +1,268 @@ { - "Aborted Connections": "Dropped Connections", - "Active": "Active", - "Active Connections": "Active Connections", - "Advanced Configuration": "Advanced Settings", - "Age": "Runtime", - "Anticipated Price": "Projected Cost", - "app": { - "Resource Quota": "Resource Limits", - "The applied CPU exceeds the quota": "CPU requested exceeds quota. Contact admin.", - "The applied GPU exceeds the quota": "GPU requested exceeds quota. Contact admin.", - "The applied memory exceeds the quota": "Memory requested exceeds quota. Contact admin.", - "The applied storage exceeds the quota": "Storage requested exceeds quota. Contact admin.", - "The container exposed port cannot be empty": "Must specify container port to expose", - "The maximum number of exposed ports is 65535": "Exposed port cannot exceed 65535", - "The minimum exposed port is 1": "Exposed port must be at least 1" - }, - "App Store": "App Store", - "Application Source": "Application Source", - "Are you sure to perform database migration": "Confirm database migration?", - "Are you sure you want to turn off automatic backup": "Confirm disabling auto backup?", + "age": "Runtime", "Auto": "Automatic", - "Auto Backup": "Automated Backup", - "Automatic backup is turned off": "Auto backup disabled", "Backup": "Backup", - "Backup Completed": "Backup completed", - "Backup Database": "Backup Database", - "Backup Deleting": "Purging Backup", - "Backup Failed": "Backup Failed", - "Backup List": "Backup History", - "Backup Name": "Backup Name", - "Backup Name cannot empty": "Must provide backup name", - "Backup Processing": "Saving Backup", - "Backup Running": "Saving Backup", - "Backup Time": "Backup Timestamp", - "Basic": "Basic", - "Billing Standards": "Pricing Guidelines", - "Block Read Time": "Block Read Duration", - "Block Write Time": "Block Write Duration", "Cancel": "Discard", - "Cannot Change Name": "Database name cannot be changed", - "Collection Name": "Collection Name", - "Command Latency": "Command Latency", - "Commits Per Second": "Transactions per Second", - "common": { - "input": { - "No Elements to Delete": "No elements selected for deletion", - "Repeat Value": "Duplicate value entered" - }, - "Surplus": "Surplus", - "Total": "Total", - "Used": "Used" - }, - "Config Form": "Configuration Form", - "Config Info": "Configuration Details", - "Confirm": "Confirm", - "Confirm Create Backup": "Confirm Create Backup?", - "Confirm Delete": "Confirm", - "Confirm delete the backup": "Confirm deleting this backup?", - "Confirm delete the migrate": "Confirm deleting the migration record?", - "Confirm Deploy DataBase?": "Confirm deploying the database?", - "Confirm Restart": "Confirm restarting this application?", - "Confirm Restart Pod": "Confirm restarting the pod?", - "Confirm to go": "Confirm Navigation", - "Confirm Update DataBase?": "Confirm updating the database?", - "Connection Info": "Connection Details", + "confirm": "Confirm", "Containers": "Containers", "Continue": "Continue", - "Continuous Migration": "Continuous Migration", - "Copy Failed": "Copy Failed", - "Copy Success": "Copy succeeded", - "Covering Risks": "Coverage Risks", - "cpu": "CPU", - "CPU": "CPU", - "Create DB": "Create New Database", "Creating": "Creating", - "Creation Time": "Creation Time", "CronExpression": "Cycle Interval", - "Current Connections": "Current Connections", - "Data Migration Config": "Data Migration Settings", + "DBList": "DataBases", "DataBase": "DataBase", - "DataBase Empty": "You don't have any databases yet", - "Database Host": "Database Hostname", - "Database Host Empty": "Please enter the database hostname", - "DataBase Info": "DataBase Info", - "Database Name": "Database Name", - "Database Name Empty": "Database name is required", - "DataBase Name Empty": "Application name is required", - "DataBase Name Regex": "Start with a letter, only allow lowercase letters, numbers and -", - "DataBase Name Regex Error": "Database name can only contain lowercase letters, numbers, -, and must start with a letter.", - "Database Password Empty": "Please enter the database password", - "Database Port Empty": "Please specify the database port", - "DataBase Size": "Storage Size", - "DataBase Type": "DataBase Type", - "Database Usage": "Database Usage", - "Database UserName Empty": "Please enter the database username", "Day": "Day", - "db instances tip": "For optimal performance, use an odd number of {{db}} instances", - "DB Name": "DataBase Name", - "DB Table": "DataBase Table", - "DBList": "DataBases", "Delete": "Delete", - "Delete anyway": "Force Delete", - "Delete Backup": "Delete Backup", - "Delete Failed": "Failed to delete", - "Delete Hint": "Warning: This will permanently delete all data in the database. Confirm to proceed.", - "Delete successful": "Deleted successfully", - "Delete Template App Tip": "To fully remove this app and all its components, please uninstall it directly from the App Store.", - "Delete Warning": "Delete Warning", "Deleting": "Deleting...", - "Deploy": "Deploy", - "Deploy DataBase": "Deploy DataBase", - "Deployment Failed": "Deployment Failed", - "Deployment Successful": "Deployed Successfully", + "deploy": "Deploy", "Details": "Details", - "Direct Connection": "connect", "Disk": "Storage Size", - "Document Operations": "Document Operations", - "Duration of Transaction": "Transaction Duration", - "Enable external network access": "Allow public network access", - "Enter Save": "Press Enter to save. 'All' exports the entire database.", - "Event Analyze": "Intelligent Analytics", - "Event Analyze Error": "Intelligent analytics error", "Export": "Export", - "External Address": "Public Domain", - "External Network": "Internet Access", "Failed": "Error", - "Failed to turn off automatic backup": "Auto Backup Disable Failed", - "file": { - "Upload Success": "File Uploaded", - "Uploading": "Uploading File ({{percent}}%)" - }, - "File upload failed": "File upload failed", "Friday": "Friday", - "Have Error": "Failed", - "Hits Ratio": "Hits Ratio", "Hour": "Hour", - "I have read and completed migration preparations": "Migration Preparations Completed", - "Import Through File": "Import via File", - "Important tips for migrating": "Tip: Create a new database in sink DB if source_database and sink_database have overlapping data, to avoid conflicts", - "InnoDB Buffer Pool": "InnoDB Buffer Pool", - "Intranet Address": "Private Address", - "Items per DB": "Keys per DB", - "jump_prompt": "Jump Notification", - "Key evictions": "Keys Evicted", - "Limit CPU": "CPU Limit", - "Limit Memory": "Memory Limit", "Logs": "Logs", - "Lost File": "File Missing", - "Manage all resources": "Manage all resources", "Manual": "Manual", - "Manual Backup": "Manual Backup", - "Manual Backup Tip": "Tip: Backup during off-peak hours. Avoid DDL operations to prevent locking. Be patient if data size is large. Backup starts 1 min after confirmation.", - "Max Replicas": "Max Replicas: ", - "Max Storage": "Max Storage: ", - "memory": "Memory", - "Memory": "Memory", - "migrate": { - "Incremental migration prompt information": "Enable \\\"Continuous Migration\\\" for incremental DB sync (disabled by default).", - "mongo": { - "check": "Source Account: Read access to DB, admin, local\\nSink Account: Read\/write access to DB, read access to admin, local" - }, - "mongodb": { - "stepOne": "# Replication cluster instance: no scaling needed. Provide primary address for migration.", - "stepTwo": "# Standalone instance: Extend to single-node replica set for CDC" - }, - "mysql": { - "stepOne": "# Set 'binlog_format' parameter to 'row'", - "stepTwo": "# Set 'binlog_row_image' parameter to 'full'" - }, - "postgresql": { - "check": "Source Account: Login access, read access to source, replication privileges\\nSink Account: Login access, read\/write access to sink", - "stepOne": "# Set 'wal_level' parameter to 'logical'", - "stepTwo": "# Ensure sufficient capacity for \\\"max_replication_slots\\\" and \\\"max_wal_senders\\\" parameters" - } - }, "Migrate": "Migrate", - "Migrate Config": "Migration Configuration", - "Migrate Now": "Migrate Now", "Migrating": "Migrating", - "Migration Failed": "Migration Failed", - "Migration Permission Check": "Verifying Migration Permissions", - "Migration Preparation": "Preparing for Migration", - "Migration prompt information": "To prevent migration failure caused by XXX, please refrain from any operations during the migration process. The migration may take a while for large datasets. Your patience is appreciated.", - "Migration Successful": "Migration Completed Successfully", - "Migration task created successfully": "Migration task created", - "Min Replicas": "Min Replicas: ", - "Min Storage": "Min Storage: ", "Monday": "Monday", - "Monitor List": "Real-Time Monitoring", "Name": "Name", - "No Data Available": "No Data Available", - "Online Import": "Import Online", - "Operation": "Operation", + "operation": "Operation", "Option": "Optional", - "Page Faults": "Page Faults", - "Parameter Error": "Invalid Parameter", "Password": "Password", "Pause": "Pause", - "Pause Error": "Failed to pause the database", - "Pause Hint": "Pausing the service will stop the calculation of charges for CPU and memory, but charges for storage and external network ports will still apply. Would you like to pause now?", - "Pause Success": "Database paused", "Paused": "Paused", "Pausing": "Pausing", "Perday": "Perday", "Performance": "Performance", - "Please Enter": "Please Enter", "Pod": "Pod", - "Pod Name": "Pod Name", "Port": "Port", - "Prompt": "Prompt", - "Query Operations": "Query Operations", - "Redis does not support backup at this time": "Backup is currently not supported for Redis", + "prompt": "Prompt", "Remark": "Note", "Replicas": "Replicas", - "Replicas Cannot Empty": "Replicas field is required", - "Replicas List": "Pod List", "Resources": "Resources", "Restart": "Restart", - "Restart Error": "Failed to restart due to an error", - "Restart Success": "Restarted successfully. Please wait...", "Restarting": "Restarting", - "Restarts": "Restart Count", - "Restore Backup": "Restore from Backup", - "Restore Backup Tip": "Restoring a backup will create a new database. Please provide a unique name for the new DB.", - "Restore Database": "Restore Database from Backup", - "Restore Success": "Backup restored successfully", - "Rollbacks Per Second": "Rollbacks\/s", + "restarts": "Restart Count", "Running": "Running", - "Running Time": "Uptime", "Saturday": "Sat", "Save": "Save", "SaveTime": "Retention Period", - "Select a maximum of 10 files": "Select up to 10 files", - "Service Deletion Failed": "Failed to delete the service", - "Set auto backup successful": "Automatic backup task set successfully", - "Slow Queries": "Slow Queries", - "Source Database": "Source Database", "Start": "Start", - "Start Backup": "Start Backup", - "Start Error": "Failed to start the database due to an error", - "Start Hour": "Hour", - "Start Minute": "Minute", - "Start Success": "Database started. Please wait...", - "Start Up": "Launch", "Starting": "Starting", "Status": "Status", - "storage": "Storage", - "Storage": "Storage", - "Storage Cannot Empty": "Please specify storage size", - "Storage Range": "Storage capacity:", - "Submit Error": "Error submitting form", "Success": "succeeded", - "Successfully closed external network access": "Internet access disabled", "Sunday": "Sun", - "Table Locks": "Table-level locks", - "Target Database": "Target Database", - "The backup task has been created successfully !": "Backup task created successfully!", - "The multi-replica Redis includes High Availability (HA) nodes, Please note, the anticipated price already encompasses the cost for the HA nodes": "Note: The price for multi-replica Redis includes HA nodes", - "The restore task has been created failed !": "Failed to create restore task", - "The Single-node database is only suitable for development testing": "Single-node DB for development and testing only", "Thursday": "Thu", - "Total Price": "Grand total", + "total_price": "total_price", "Tuesday": "Tue", - "Turn On": "Enable", "Type": "Type", - "Update": "Update", - "Update DataBase": "Update DataBase", - "Update Failed": "Update Failed", - "Update Successful": "Update succeeded", - "Update Time": "Update Time", + "Unknown": "Unknown", + "update": "Update", "Updating": "Updating", - "Upload dump file": "Upload Dump File", - "Upload successful": "Upload Successfully", - "Use Docs": "Documentation", "Username": "Username", - "Version": "Version", "Wednesday": "Wed", "Week": "Week", - "YAML File": "YAML", - "remark_tip": "Contains up to 10 Chinese characters and 30 English characters" + "aborted_connections": "Dropped Connections", + "active_connections": "Active Connections", + "advanced_configuration": "Advanced Settings", + "anticipated_price": "Projected Cost", + "app": { + "resource_quota": "Resource Limits", + "cpu_exceeds_quota": "CPU requested exceeds quota. Contact admin.", + "memory_exceeds_quota": "Memory requested exceeds quota. Contact admin.", + "storage_exceeds_quota": "Storage requested exceeds quota. Contact admin." + }, + "app_store": "App Store", + "application_source": "Application Source", + "are_you_sure_to_perform_database_migration": "Confirm database migration?", + "are_you_sure_you_want_to_turn_off_automatic_backup": "Confirm disabling auto backup?", + "auto_backup": "Automated Backup", + "automatic_backup_is_turned_off": "Auto backup disabled", + "backup_completed": "Backup completed", + "backup_database": "Backup Database", + "backup_deleting": "Purging Backup", + "backup_failed": "Backup Failed", + "backup_list": "Backup History", + "backup_name": "Backup Name", + "backup_name_cannot_empty": "Must provide backup name", + "backup_processing": "Saving Backup", + "backup_running": "Saving Backup", + "backup_success_tip": "The backup task has been successfully created", + "backup_time": "Backup Timestamp", + "basic": "Basic", + "billing_standards": "Pricing Guidelines", + "block_read_time": "Block Read Duration", + "block_write_time": "Block Write Duration", + "cannot_change_name": "Database name cannot be changed", + "collection_name": "Collection Name", + "command_latency": "Command Latency", + "commits_per_second": "Transactions per Second", + "common": { + "Surplus": "Surplus", + "Total": "Total", + "Used": "Used", + "input": { + "No Elements to Delete": "No elements selected for deletion", + "Repeat Value": "Duplicate value entered" + } + }, + "config_form": "Form", + "config_info": "Configuration Details", + "confirm_delete": "Confirm", + "confirm_delete_the_backup": "Confirm deleting this backup?", + "confirm_delete_the_migrate": "Confirm deleting the migration record?", + "confirm_deploy_database": "Confirm deploying the database?", + "confirm_restart": "Confirm restarting this application?", + "confirm_restart_pod": "Confirm restarting the pod?", + "confirm_to_go": "Confirm Navigation", + "confirm_update_database": "Confirm updating the database?", + "connection_info": "Connection Details", + "continuous_migration": "Continuous Migration", + "copy_failed": "Copy Failed", + "copy_success": "Copy succeeded", + "covering_risks": "Coverage Risks", + "cpu": "CPU", + "create_db": "Create New Database", + "creation_time": "Creation Time", + "current_connections": "Current Connections", + "data_migration_config": "Data Migration Settings", + "database_empty": "You don't have any databases yet", + "database_host": "Database Hostname", + "database_host_empty": "Please enter the database hostname", + "database_name": "Database Name", + "database_name_cannot_empty": "Database name cannot be empty", + "database_name_empty": "Application name is required", + "database_name_regex": "Start with a letter, only allow lowercase letters, numbers and -", + "database_name_regex_error": "Database name can only contain lowercase letters, numbers, -, and must start with a letter.", + "database_password_empty": "Please enter the database password", + "database_port_empty": "Please specify the database port", + "database_type": "DataBase Type", + "database_usage": "Database Usage", + "database_username_empty": "Please enter the database username", + "db_instances_tip": "For optimal performance, use an odd number of {{db}} instances", + "db_name": "DataBase Name", + "db_table": "DataBase Table", + "delete_anyway": "Force Delete", + "delete_backup": "Delete Backup", + "delete_failed": "Failed to delete", + "delete_hint": "Warning: This will permanently delete all data in the database. Confirm to proceed.", + "delete_successful": "Deleted successfully", + "delete_template_app_tip": "To fully remove this app and all its components, please uninstall it directly from the App Store.", + "delete_warning": "Delete Warning", + "deploy_database": "Deploy DataBase", + "deployment_failed": "Deployment Failed", + "deployment_successful": "Deployed Successfully", + "direct_connection": "connect", + "document_operations": "Document Operations", + "duration_of_transaction": "Transaction Duration", + "enable_external_network_access": "Allow public network access", + "enter_save": "Press Enter to save. 'All' exports the entire database.", + "event_analyze": "Intelligent Analytics", + "event_analyze_error": "Intelligent analytics error", + "external_address": "Public Domain", + "external_network": "Internet Access", + "failed_to_turn_off_automatic_backup": "Auto Backup Disable Failed", + "file": { + "Upload Success": "File Uploaded", + "Uploading": "Uploading File ({{percent}}%)" + }, + "file_upload_failed": "File upload failed", + "have_error": "Failed", + "hits_ratio": "Hits Ratio", + "migration_preparations": "Migration Preparations Completed", + "import_through_file": "Import via File", + "important_tips_for_migrating": "Tip: Create a new database in sink DB if source_database and sink_database have overlapping data, to avoid conflicts", + "innodb_buffer_pool": "InnoDB Buffer Pool", + "intranet_address": "Private Address", + "items_per_db": "Keys per DB", + "jump_prompt": "Jump Notification", + "key_evictions": "Keys Evicted", + "limit_cpu": "CPU Limit", + "limit_memory": "Memory Limit", + "lost_file": "File Missing", + "manage_all_resources": "Manage all resources", + "manual_backup": "Manual Backup", + "manual_backup_tip": "Tip: Backup during off-peak hours. Avoid DDL operations to prevent locking. Be patient if data size is large. Backup starts 1 min after confirmation.", + "max_replicas": "Max Replicas: ", + "memory": "Memory", + "migrate": { + "Incremental migration prompt information": "Enable \\\"Continuous Migration\\\" for incremental DB sync (disabled by default).", + "mongo": { + "check": "Source Account: Read access to DB, admin, local\\nSink Account: Read/write access to DB, read access to admin, local" + }, + "mongodb": { + "stepOne": "# Replication cluster instance: no scaling needed. Provide primary address for migration.", + "stepTwo": "# Standalone instance: Extend to single-node replica set for CDC" + }, + "mysql": { + "stepOne": "# Set 'binlog_format' parameter to 'row'", + "stepTwo": "# Set 'binlog_row_image' parameter to 'full'" + }, + "postgresql": { + "check": "Source Account: Login access, read access to source, replication privileges\\nSink Account: Login access, read/write access to sink", + "stepOne": "# Set 'wal_level' parameter to 'logical'", + "stepTwo": "# Ensure sufficient capacity for \\\"max_replication_slots\\\" and \\\"max_wal_senders\\\" parameters" + } + }, + "migrate_config": "Migration Configuration", + "migrate_now": "Migrate Now", + "migration_failed": "Migration Failed", + "migration_permission_check": "Verifying Migration Permissions", + "migration_preparation": "Preparing for Migration", + "migration_prompt_information": "To prevent migration failure caused by XXX, please refrain from any operations during the migration process. The migration may take a while for large datasets. Your patience is appreciated.", + "migration_successful": "Migration Completed Successfully", + "migration_task_created_successfully": "Migration task created", + "min_replicas": "Min Replicas: ", + "monitor_list": "Monitoring", + "multi_replica_redis_tip": "Note: The price for multi-replica Redis includes HA nodes", + "no_data_available": "No Data Available", + "not_allow_standalone_use": "This application is not allowed to be used alone. Click OK to go to Sealos Desktop for use.", + "online_import": "Import Online", + "page_faults": "Page Faults", + "pause_error": "Failed to pause the database", + "pause_hint": "Pausing the service will stop the calculation of charges for CPU and memory, but charges for storage and external network ports will still apply. Would you like to pause now?", + "pause_success": "Database paused", + "please_enter": "Please Enter", + "Pod Name": "Pod Name", + "query_operations": "Query Operations", + "remark_tip": "Contains up to 10 Chinese characters and 30 English characters", + "remind": "remind", + "replicas_cannot_empty": "Replicas field is required", + "replicas_list": "Pod List", + "restart_error": "Failed to restart due to an error", + "restart_success": "Restarted successfully. Please wait...", + "restore_backup": "Restore from Backup", + "restore_backup_tip": "Restoring a backup will create a new database. Please provide a unique name for the new DB.", + "restore_database": "Restore Database from Backup", + "restore_success": "Backup restored successfully", + "rollbacks_per_second": "Rollbacks/s", + "running_time": "Uptime", + "select_a_maximum_of_10_files": "Select up to 10 files", + "service_deletion_failed": "Failed to delete the service", + "set_auto_backup_successful": "Automatic backup task set successfully", + "slow_queries": "Slow Queries", + "source_database": "Source Database", + "start_backup": "Start Backup", + "start_error": "Failed to start the database due to an error", + "start_hour": "Hour", + "start_minute": "Minute", + "start_success": "Database started. Please wait...", + "storage": "Storage", + "storage_cannot_empty": "Please specify storage size", + "storage_max": "maximum storage", + "storage_min": "Minimum storage", + "storage_range": "Storage capacity:", + "submit_error": "Error submitting form", + "successfully_closed_external_network_access": "Internet access disabled", + "table_locks": "Table-level locks", + "single_node_tip": "Single-node DB for development and testing only", + "turn_on": "Enable", + "update_database": "Update DataBase", + "update_failed": "Update Failed", + "update_successful": "Update succeeded", + "update_time": "Update Time", + "upload_dump_file": "Upload Dump File", + "use_docs": "Documentation", + "version": "Version", + "yaml_file": "YAML" } \ No newline at end of file diff --git a/frontend/providers/dbprovider/public/locales/zh/common.json b/frontend/providers/dbprovider/public/locales/zh/common.json index 723efdbdf3a..95ed772beb6 100644 --- a/frontend/providers/dbprovider/public/locales/zh/common.json +++ b/frontend/providers/dbprovider/public/locales/zh/common.json @@ -1,283 +1,268 @@ { - "Aborted Connections": "异常连接数", - "Active": "活跃", - "Active Connections": "活跃连接数", - "Advanced Configuration": "高级配置", - "Age": "运行时长", - "Anticipated Price": "预估价格", - "app": { - "Resource Quota": "资源配额", - "The applied CPU exceeds the quota": "申请的 CPU 超出限制,请联系管理员", - "The applied GPU exceeds the quota": "申请的 GPU 超出限制,请联系管理员", - "The applied memory exceeds the quota": "申请的 '内存' 超出限制,请联系管理员", - "The applied storage exceeds the quota": "申请的 '存储' 超出限制,请联系管理员", - "The container exposed port cannot be empty": "容器暴露端口不能为空", - "The maximum number of exposed ports is 65535": "暴露端口最大为65535", - "The minimum exposed port is 1": "暴露端口最小为 1" - }, - "App Store": "应用商店", - "Application Source": "应用来源", - "Are you sure to perform database migration": "确定执行数据库迁移吗?", - "Are you sure you want to turn off automatic backup": "确定关闭自动备份吗", + "age": "运行时长", "Auto": "自动", - "Auto Backup": "自动备份", - "Automatic backup is turned off": "已关闭自动备份", "Backup": "备份", - "Backup Completed": "备份成功", - "Backup Database": "备份数据库", - "Backup Deleting": "删除中", - "Backup Failed": "备份失败", - "Backup List": "备份历史", - "Backup Name": "备份名", - "Backup Name cannot empty": "备份名称不能为空", - "Backup Processing": "备份中", - "Backup Running": "备份中", - "Backup Time": "备份时间", - "Basic": "基础配置", - "Billing Standards": "计费标准", - "Block Read Time": "读数据块时间", - "Block Write Time": "写数据块时间", + "basic": "基础配置", "Cancel": "取消", - "Cannot Change Name": "不允许修改数据库名称", - "Collection Name": "集合名称", - "Command Latency": "命令延迟", - "Commits Per Second": "事务数", - "common": { - "input": { - "No Elements to Delete": "没有要删除的元素", - "Repeat Value": "输入重复值" - }, - "Surplus": "剩余", - "Total": "总共", - "Used": "已用" - }, - "Config Form": "配置表单", - "Config Info": "配置信息", - "Confirm": "确认", - "Confirm Create Backup": "确认创建备份任务?", - "Confirm Delete": "确认删除", - "Confirm delete the backup": "确认删除该备份?", - "Confirm delete the migrate": "确定删除迁移记录吗?", - "Confirm Deploy DataBase?": "确认部署数据库?", - "Confirm Restart": "确认重启该应用?", - "Confirm Restart Pod": "请确认重启 Pod?", - "Confirm to go": "确认前往", - "Confirm Update DataBase?": "确认更新数据库?", - "Connection Info": "连接信息", + "confirm": "确认", "Containers": "容器", "Continue": "继续", - "Continuous Migration": "持续迁移", - "Copy Failed": "复制失败", - "Copy Success": "复制成功", - "Covering Risks": "覆盖风险", - "cpu": "CPU", - "CPU": "CPU", - "Create DB": "新建数据库", "Creating": "创建中", - "Creation Time": "创建时间", "CronExpression": "循环周期", - "Current Connections": "当前连接数", - "Data Migration Config": "数据迁移配置", + "DBList": "数据库列表", "DataBase": "数据库", - "DataBase Empty": "您还没有数据库", - "Database Host": "数据库主机名", - "Database Host Empty": "缺少数据库主机名", - "DataBase Info": "数据库信息", - "Database Name": "新数据库名", - "Database Name Empty": "数据库名称不能为空", - "DataBase Name Empty": "应用名称不能为空", - "DataBase Name Regex": "字母开头,仅能包含小写字母、数字和 -", - "DataBase Name Regex Error": "数据库名只能包含小写字母、数字和 -,并且字母开头。", - "Database Password Empty": "缺少数据库密码", - "Database Port Empty": "缺少数据库端口", - "DataBase Size": "磁盘空间", - "DataBase Type": "数据库类型", - "Database Usage": "数据库用量", - "Database UserName Empty": "缺少数据库用户名", "Day": "天", - "db instances tip": "{{db}} 实例数量建议为奇数", - "DB Name": "数据库名字", - "DB Table": "数据库表", - "DBList": "数据库列表", "Delete": "删除", - "Delete anyway": "仍要删除", - "Delete Backup": "删除备份", - "Delete Failed": "删除出现意外", - "Delete Hint": "如果确认要删除这个数据库吗?如果执行此操作,将删除该数据库的所有数据。", - "Delete successful": "删除成功", - "Delete Template App Tip": "该应用是通过应用商店部署的,如果您想完全卸载该应用并清理所有相关的组件,请到应用商店中将整个应用删除。", - "Delete Warning": "删除警告", "Deleting": "删除中", - "Deploy": "部署", - "Deploy DataBase": "部署数据库", - "Deployment Failed": "部署失败", - "Deployment Successful": "部署成功", + "deploy": "部署", "Details": "详情", - "Direct Connection": "连接", "Disk": "磁盘空间", - "Document Operations": "文档操作数", - "Duration of Transaction": "事务持续时间", - "Enable external network access": "开启外网访问", - "Enter Save": "回车保存 && All 代表导出整个库", - "Event Analyze": "智能分析", - "Event Analyze Error": "智能分析出错了~", "Export": "导出", - "External Address": "外网地址", - "External Network": "外网访问", "Failed": "有异常", - "Failed to turn off automatic backup": "关闭自动备份失败", - "file": { - "Upload Success": "文件上传成功", - "Uploading": "正在上传文件,进度: {{percent}}%" - }, - "File upload failed": "文件上传失败", "Friday": "周五", - "Have Error": "出现异常", - "Hits Ratio": "命中率", "Hour": "小时", - "I have read and completed migration preparations": "我已阅读并完成迁移准备工作", - "Import Through File": "文件导入", - "Important tips for migrating": "如果 source 数据库中 source_database 和 sink 数据库中 sink_database 的数据库有重叠,应该在sink 数据库中新建 database,以免出现数据重叠", - "InnoDB Buffer Pool": "InnoDB 缓冲池", - "Intranet Address": "内网地址", - "Items per DB": "键值数", - "jump_prompt": "跳转提示", - "Key evictions": "键驱逐数", - "Limit CPU": "最大 CPU", - "Limit Memory": "最大内存", "Logs": "日志", - "Lost File": "缺少文件", - "Manage all resources": "管理所有资源", "Manual": "手动", - "Manual Backup": "手动备份", - "Manual Backup Tip": "建议在业务低峰期备份实例。备份期间,请勿执行DDL操作,避免锁表导致备份失败。若数据量较大,花费的时问可能较长,请耐心等待。点击 [开始备份] 后,将在1分钟后开始备份。", - "Max Replicas": "实例数最大为: ", - "Max Storage": "磁盘容量最大为: ", - "memory": "内存", - "Memory": "内存", - "migrate": { - "Incremental migration prompt information": "如果需要数据库增量同步,可以开启\"持续迁移\",默认是关闭。", - "mongo": { - "check": "source account: 待迁移仓库的读权限、admin、local\nsink account: 待迁移仓库的读写权限以及admin和local的读权限" - }, - "mongodb": { - "stepOne": "# 复制集群实例: 无需伸缩。需要提供用于迁移的主地址的地址", - "stepTwo": "# Standalone实例:需要将Standalone扩展到一个节点的副本集才能使用CDC" - }, - "mysql": { - "stepOne": "# 设置 'binlog_format' 配置为 'row'", - "stepTwo": "# 设置 'binlog_row_image' 配置为'full'" - }, - "postgresql": { - "check": "source account:登录权限、源迁移对象的读权限、复制权限 \nsink account:登录权限、Sink的读\/写权限", - "stepOne": "# 设置 'wal_level' 配置为 'logical'", - "stepTwo": "# 确保配置的\"max_replication_slots\"、\"max_wal_senders\"数量足够" - } - }, "Migrate": "迁移", - "Migrate Config": "迁移配置", - "Migrate Now": "立即迁移", "Migrating": "正在迁移", - "Migration Failed": "迁移失败", - "Migration Permission Check": "迁移权限检查", - "Migration Preparation": "迁移准备", - "Migration prompt information": "迁移时请勿执行操作,以免因XXX导致迁移失败。如数据量较大,迁移时间可能较长,请耐心等待", - "Migration Successful": "迁移成功", - "Migration task created successfully": "迁移任务创建成功", - "Min Replicas": "实例数最小为: ", - "Min Storage": "磁盘容量最小为: ", "Monday": "周一", - "Monitor List": "实时监控", "Name": "名字", - "No Data Available": "暂无数据", - "Online Import": "在线导入", - "Operation": "操作", + "operation": "操作", "Option": "选填", - "Page Faults": "页错误", - "Parameter Error": "参数错误", "Password": "密码", "Pause": "暂停", - "Pause Error": "数据库暂停失败", - "Pause Hint": "暂停服务将停止计算 CPU 和内存等费用,但存储和外网端口仍将产生费用。是否现在暂停?", - "Pause Success": "数据库已暂停", "Paused": "已暂停", "Pausing": "暂停中", "Perday": "每日", "Performance": "性能", - "Please Enter": "请输入", "Pod": "实例", - "Pod Name": "实例名", "Port": "端口", - "Prompt": "提示", - "Query Operations": "查询操作数", - "Redis does not support backup at this time": "Redis 暂时不支持备份", + "prompt": "提示", "Remark": "备注", - "Remind": "提醒", + "remind": "提醒", "Replicas": "实例数", - "Replicas Cannot Empty": "实例数不能为空", - "Replicas List": "实例列表", "Resources": "资源", "Restart": "重启", - "Restart Error": "重启出现了意外", - "Restart Success": "重启成功,请等待", "Restarting": "重启中", - "Restarts": "重启次数", - "Restore Backup": "恢复备份", - "Restore Backup Tip": "恢复备份会创建一个新的数据库,你需要提供新的数据库名,并且不能与当前数据库重名。", - "Restore Database": "恢复数据库备份", - "Restore Success": "恢复备份成功", - "Rollbacks Per Second": "回滚数", + "restarts": "重启次数", "Running": "运行中", - "Running Time": "运行时长", "Saturday": "周六", "Save": "保存", "SaveTime": "保留时间", - "Select a maximum of 10 files": "最多选择 10 个文件", - "Service Deletion Failed": "Service 删除失败", - "Set auto backup successful": "设置自动备份任务成功", - "Slow Queries": "慢查询", - "Source Database": "源数据库", "Start": "开始", - "Start Backup": "开始备份", - "Start Error": "数据库启动出现意外", - "Start Hour": "小时", - "Start Minute": "分钟", - "Start Success": "数据库启动成功,请等待", - "Start Up": "启动", "Starting": "启动中", "Status": "状态", - "storage": "磁盘", - "Storage": "磁盘", - "Storage Cannot Empty": "容量不能为空", - "Storage Range": "容量范围: ", - "Submit Error": "提交表单错误", + "storage_max": "最大存储", + "storage_min": "最小存储", "Success": "成功", - "Successfully closed external network access": "已关闭外网访问", "Sunday": "周日", - "Table Locks": "表锁", - "Target Database": "目标数据库", - "The backup task has been created successfully !": "备份任务创建成功!", - "The multi-replica Redis includes High Availability (HA) nodes, Please note, the anticipated price already encompasses the cost for the HA nodes": "Redis 多副本包含 HA 节点,请悉知,预估价格已包含 HA 节点费用", - "The restore task has been created failed !": "恢复备份任务创建失败", - "The Single-node database is only suitable for development testing": "单节点数据库仅适用开发测试", "Thursday": "周四", - "Total Price": "总价", "Tuesday": "周二", - "Turn On": "开启", "Type": "类型", - "Update": "变更", - "Update DataBase": "变更数据库", - "Update Failed": "更新失败", - "Update Successful": "更新成功", - "Update Time": "更新时间", + "Unknown": "未知", + "update": "变更", "Updating": "变更中", - "Upload dump file": "点击上传 Dump 文件", - "Upload successful": "文件上传成功", - "Use Docs": "使用文档", "Username": "用户名", - "Version": "版本", + "version": "版本", "Wednesday": "周三", "Week": "周", - "YAML File": "YAML 文件", - "remark_tip": "最多包含10个中文字符,30个英文字符。" + "aborted_connections": "异常连接数", + "active_connections": "活跃连接数", + "advanced_configuration": "高级配置", + "anticipated_price": "预估价格", + "app": { + "resource_quota": "资源配额", + "cpu_exceeds_quota": "申请的 CPU 超出限制,请联系管理员", + "memory_exceeds_quota": "申请的 '内存' 超出限制,请联系管理员", + "storage_exceeds_quota": "申请的 '存储' 超出限制,请联系管理员" + }, + "app_store": "应用商店", + "application_source": "应用来源", + "are_you_sure_to_perform_database_migration": "确定执行数据库迁移吗?", + "are_you_sure_you_want_to_turn_off_automatic_backup": "确定关闭自动备份吗", + "auto_backup": "自动备份", + "automatic_backup_is_turned_off": "已关闭自动备份", + "backup_completed": "备份成功", + "backup_database": "备份数据库", + "backup_deleting": "删除中", + "backup_failed": "备份失败", + "backup_list": "备份历史", + "backup_name": "备份名", + "backup_name_cannot_empty": "备份名称不能为空", + "backup_processing": "备份中", + "backup_running": "备份中", + "backup_success_tip": "备份任务已经成功创建", + "backup_time": "备份时间", + "billing_standards": "计费标准", + "block_read_time": "读数据块时间", + "block_write_time": "写数据块时间", + "cannot_change_name": "不允许修改数据库名称", + "collection_name": "集合名称", + "command_latency": "命令延迟", + "commits_per_second": "事务数", + "common": { + "Surplus": "剩余", + "Total": "总共", + "Used": "已用", + "input": { + "No Elements to Delete": "没有要删除的元素", + "Repeat Value": "输入重复值" + } + }, + "config_form": "配置表单", + "config_info": "配置信息", + "confirm_delete": "确认删除", + "confirm_delete_the_backup": "确认删除该备份?", + "confirm_delete_the_migrate": "确定删除迁移记录吗?", + "confirm_deploy_database": "确认部署数据库?", + "confirm_restart": "确认重启该应用?", + "confirm_restart_pod": "请确认重启 Pod?", + "confirm_to_go": "确认前往", + "confirm_update_database": "确认更新数据库?", + "connection_info": "连接信息", + "continuous_migration": "持续迁移", + "copy_failed": "复制失败", + "copy_success": "复制成功", + "covering_risks": "覆盖风险", + "cpu": "CPU", + "create_db": "新建数据库", + "creation_time": "创建时间", + "current_connections": "当前连接数", + "data_migration_config": "数据迁移配置", + "database_empty": "您还没有数据库", + "database_host": "数据库主机名", + "database_host_empty": "缺少数据库主机名", + "database_name": "新数据库名", + "database_name_cannot_empty": "数据库名称不能为空", + "database_name_empty": "应用名称不能为空", + "database_name_regex": "字母开头,仅能包含小写字母、数字和 -", + "database_name_regex_error": "数据库名只能包含小写字母、数字和 -,并且字母开头。", + "database_password_empty": "缺少数据库密码", + "database_port_empty": "缺少数据库端口", + "database_type": "数据库类型", + "database_usage": "数据库用量", + "database_username_empty": "缺少数据库用户名", + "db_instances_tip": "{{db}} 实例数量建议为奇数", + "db_name": "数据库名字", + "db_table": "数据库表", + "delete_anyway": "仍要删除", + "delete_backup": "删除备份", + "delete_failed": "删除出现意外", + "delete_hint": "如果确认要删除这个数据库吗?如果执行此操作,将删除该数据库的所有数据。", + "delete_successful": "删除成功", + "delete_template_app_tip": "该应用是通过应用商店部署的,如果您想完全卸载该应用并清理所有相关的组件,请到应用商店中将整个应用删除。", + "delete_warning": "删除警告", + "deploy_database": "部署数据库", + "deployment_failed": "部署失败", + "deployment_successful": "部署成功", + "direct_connection": "连接", + "document_operations": "文档操作数", + "duration_of_transaction": "事务持续时间", + "enable_external_network_access": "开启外网访问", + "enter_save": "回车保存 && All 代表导出整个库", + "event_analyze": "智能分析", + "event_analyze_error": "智能分析出错了~", + "external_address": "外网地址", + "external_network": "外网访问", + "failed_to_turn_off_automatic_backup": "关闭自动备份失败", + "file": { + "Upload Success": "文件上传成功", + "Uploading": "正在上传文件,进度: {{percent}}%" + }, + "file_upload_failed": "文件上传失败", + "have_error": "出现异常", + "hits_ratio": "命中率", + "migration_preparations": "我已阅读并完成迁移准备工作", + "import_through_file": "文件导入", + "important_tips_for_migrating": "如果 source 数据库中 source_database 和 sink 数据库中 sink_database 的数据库有重叠,应该在sink 数据库中新建 database,以免出现数据重叠", + "innodb_buffer_pool": "InnoDB 缓冲池", + "intranet_address": "内网地址", + "items_per_db": "键值数", + "jump_prompt": "跳转提示", + "key_evictions": "键驱逐数", + "limit_cpu": "最大 CPU", + "limit_memory": "最大内存", + "lost_file": "缺少文件", + "manage_all_resources": "管理所有资源", + "manual_backup": "手动备份", + "manual_backup_tip": "建议在业务低峰期备份实例。备份期间,请勿执行DDL操作,避免锁表导致备份失败。若数据量较大,花费的时问可能较长,请耐心等待。点击 [开始备份] 后,将在1分钟后开始备份。", + "max_replicas": "实例数最大为: ", + "memory": "内存", + "migrate": { + "Incremental migration prompt information": "如果需要数据库增量同步,可以开启\"持续迁移\",默认是关闭。", + "mongo": { + "check": "source account: 待迁移仓库的读权限、admin、local\nsink account: 待迁移仓库的读写权限以及admin和local的读权限" + }, + "mongodb": { + "stepOne": "# 复制集群实例: 无需伸缩。需要提供用于迁移的主地址的地址", + "stepTwo": "# Standalone实例:需要将Standalone扩展到一个节点的副本集才能使用CDC" + }, + "mysql": { + "stepOne": "# 设置 'binlog_format' 配置为 'row'", + "stepTwo": "# 设置 'binlog_row_image' 配置为'full'" + }, + "postgresql": { + "check": "source account:登录权限、源迁移对象的读权限、复制权限 \nsink account:登录权限、Sink的读/写权限", + "stepOne": "# 设置 'wal_level' 配置为 'logical'", + "stepTwo": "# 确保配置的\"max_replication_slots\"、\"max_wal_senders\"数量足够" + } + }, + "migrate_config": "迁移配置", + "migrate_now": "立即迁移", + "migration_failed": "迁移失败", + "migration_permission_check": "迁移权限检查", + "migration_preparation": "迁移准备", + "migration_prompt_information": "迁移时请勿执行操作,以免因XXX导致迁移失败。如数据量较大,迁移时间可能较长,请耐心等待", + "migration_successful": "迁移成功", + "migration_task_created_successfully": "迁移任务创建成功", + "min_replicas": "实例数最小为: ", + "monitor_list": "实时监控", + "no_data_available": "暂无数据", + "not_allow_standalone_use": "该应用不允许单独使用,点击确认前往 Sealos Desktop 使用。", + "online_import": "在线导入", + "page_faults": "页错误", + "pause_error": "数据库暂停失败", + "pause_hint": "暂停服务将停止计算 CPU 和内存等费用,但存储和外网端口仍将产生费用。是否现在暂停?", + "pause_success": "数据库已暂停", + "please_enter": "请输入", + "Pod Name": "实例名", + "query_operations": "查询操作数", + "remark_tip": "最多包含10个中文字符,30个英文字符。", + "replicas_cannot_empty": "实例数不能为空", + "replicas_list": "实例列表", + "restart_error": "重启出现了意外", + "restart_success": "重启成功,请等待", + "restore_backup": "恢复备份", + "restore_backup_tip": "恢复备份会创建一个新的数据库,你需要提供新的数据库名,并且不能与当前数据库重名。", + "restore_database": "恢复数据库备份", + "restore_success": "恢复备份成功", + "rollbacks_per_second": "回滚数", + "running_time": "运行时长", + "select_a_maximum_of_10_files": "最多选择 10 个文件", + "service_deletion_failed": "Service 删除失败", + "set_auto_backup_successful": "设置自动备份任务成功", + "slow_queries": "慢查询", + "source_database": "源数据库", + "start_backup": "开始备份", + "start_error": "数据库启动出现意外", + "start_hour": "小时", + "start_minute": "分钟", + "start_success": "数据库启动成功,请等待", + "storage": "磁盘", + "storage_cannot_empty": "容量不能为空", + "storage_range": "容量范围: ", + "submit_error": "提交表单错误", + "successfully_closed_external_network_access": "已关闭外网访问", + "table_locks": "表锁", + "multi_replica_redis_tip": "Redis 多副本包含 HA 节点,请悉知,预估价格已包含 HA 节点费用", + "single_node_tip": "单节点数据库仅适用开发测试", + "total_price": "总价", + "turn_on": "开启", + "update_database": "变更数据库", + "update_failed": "更新失败", + "update_successful": "更新成功", + "update_time": "更新时间", + "upload_dump_file": "点击上传 Dump 文件", + "use_docs": "使用文档", + "yaml_file": "YAML 文件" } \ No newline at end of file diff --git a/frontend/providers/dbprovider/src/components/DBStatusTag/index.tsx b/frontend/providers/dbprovider/src/components/DBStatusTag/index.tsx index d2fea057446..c1e5ee9a957 100644 --- a/frontend/providers/dbprovider/src/components/DBStatusTag/index.tsx +++ b/frontend/providers/dbprovider/src/components/DBStatusTag/index.tsx @@ -14,6 +14,7 @@ import type { DBConditionItemType, DBStatusMapType } from '@/types/db'; import MyIcon from '../Icon'; import { useTranslation } from 'next-i18next'; import { formatPodTime } from '@/utils/tools'; +import { I18nCommonKey } from '@/types/i18next'; const DBStatusTag = ({ conditions = [], @@ -26,6 +27,7 @@ const DBStatusTag = ({ }) => { const { t } = useTranslation(); const { isOpen, onOpen, onClose } = useDisclosure(); + const label = t(status.label as I18nCommonKey); return ( <> @@ -45,7 +47,7 @@ const DBStatusTag = ({ > - {t(status.label)} + {label} @@ -53,7 +55,7 @@ const DBStatusTag = ({ - {t(status.label)} + {label} diff --git a/frontend/providers/dbprovider/src/components/FileSelect/index.tsx b/frontend/providers/dbprovider/src/components/FileSelect/index.tsx index 128ceb9cd58..a73d23d24ee 100644 --- a/frontend/providers/dbprovider/src/components/FileSelect/index.tsx +++ b/frontend/providers/dbprovider/src/components/FileSelect/index.tsx @@ -50,7 +50,7 @@ const FileSelect = ({ fileExtension, setFiles, multiple = false, files, ...props > - {t('Upload dump file')} + {t('upload_dump_file')} 10) { return toast({ status: 'warning', - title: t('Select a maximum of 10 files') + title: t('select_a_maximum_of_10_files') }); } onSelectFile(Array.from(e.target.files)); diff --git a/frontend/providers/dbprovider/src/components/PriceBox/index.tsx b/frontend/providers/dbprovider/src/components/PriceBox/index.tsx index 5c402d7f81c..57216b1bdd4 100644 --- a/frontend/providers/dbprovider/src/components/PriceBox/index.tsx +++ b/frontend/providers/dbprovider/src/components/PriceBox/index.tsx @@ -1,4 +1,5 @@ import { SOURCE_PRICE } from '@/store/static'; +import { I18nCommonKey } from '@/types/i18next'; import { Box, Flex, useTheme, Text } from '@chakra-ui/react'; import { SealosCoin } from '@sealos/ui'; import { useTranslation } from 'next-i18next'; @@ -22,7 +23,11 @@ const PriceBox = ({ }) => { const theme = useTheme(); const { t } = useTranslation(); - const priceList = useMemo(() => { + const priceList: { + label: I18nCommonKey; + color: string; + value: string; + }[] = useMemo(() => { let cp = [0, 0]; let mp = [0, 0]; let sp = [0, 0]; @@ -49,13 +54,13 @@ const PriceBox = ({ return [ { - label: 'CPU', + label: 'cpu', color: '#33BABB', value: podScale(cp) }, - { label: 'Memory', color: '#36ADEF', value: podScale(mp) }, - { label: 'Storage', color: '#8172D8', value: podScale(sp) }, - { label: 'Total Price', color: '#485058', value: podScale(tp) } + { label: 'memory', color: '#36ADEF', value: podScale(mp) }, + { label: 'storage', color: '#8172D8', value: podScale(sp) }, + { label: 'total_price', color: '#485058', value: podScale(tp) } ]; }, [components]); @@ -63,7 +68,7 @@ const PriceBox = ({ - {t('Anticipated Price')} + {t('anticipated_price')} ({t('Perday')}) diff --git a/frontend/providers/dbprovider/src/components/QuotaBox/index.tsx b/frontend/providers/dbprovider/src/components/QuotaBox/index.tsx index 9be7a20b941..b8429c0e72d 100644 --- a/frontend/providers/dbprovider/src/components/QuotaBox/index.tsx +++ b/frontend/providers/dbprovider/src/components/QuotaBox/index.tsx @@ -56,7 +56,7 @@ ${t('common.Surplus')}: ${(limit - used).toFixed(2)} ${unit}`; color={'grayModern.900'} fontWeight={500} > - {t('app.Resource Quota')} + {t('app.resource_quota')} {quotaList.map((item) => ( diff --git a/frontend/providers/dbprovider/src/components/Textarea/TagTextarea.tsx b/frontend/providers/dbprovider/src/components/Textarea/TagTextarea.tsx index 93331ee3d34..1dfa13b4ece 100644 --- a/frontend/providers/dbprovider/src/components/Textarea/TagTextarea.tsx +++ b/frontend/providers/dbprovider/src/components/Textarea/TagTextarea.tsx @@ -84,7 +84,7 @@ const TagTextarea = ({ defaultValues, onUpdate, ...props }: Props) => { ))} = { [BackupStatusEnum.Completed]: { - label: 'Backup Completed', + label: 'backup_completed', value: BackupStatusEnum.Completed, color: '#039855' }, [BackupStatusEnum.InProgress]: { - label: 'Backup Processing', + label: 'backup_processing', value: BackupStatusEnum.InProgress, color: '#667085' }, [BackupStatusEnum.Failed]: { - label: 'Backup Failed', + label: 'backup_failed', value: BackupStatusEnum.Failed, color: '#F04438' }, [BackupStatusEnum.Running]: { - label: 'Backup Running', + label: 'backup_running', value: BackupStatusEnum.Running, color: '#667085' }, [BackupStatusEnum.Deleting]: { - label: 'Backup Deleting', + label: 'backup_deleting', value: BackupStatusEnum.Deleting, color: '#DC6803' }, @@ -53,7 +54,7 @@ export enum BackupTypeEnum { 'UnKnow' = 'UnKnow' } -export const backupTypeMap: Record<`${BackupTypeEnum}`, { label: string }> = { +export const backupTypeMap: Record<`${BackupTypeEnum}`, { label: I18nCommonKey }> = { [BackupTypeEnum.manual]: { label: 'Manual' }, diff --git a/frontend/providers/dbprovider/src/constants/editApp.ts b/frontend/providers/dbprovider/src/constants/editApp.ts index 9a74394db0c..5fbacb5701f 100644 --- a/frontend/providers/dbprovider/src/constants/editApp.ts +++ b/frontend/providers/dbprovider/src/constants/editApp.ts @@ -1,20 +1,24 @@ -export const editModeMap = (isEdit: boolean) => { +import { I18nCommonKey } from '@/types/i18next'; + +export const editModeMap: (isEdit: boolean) => { + [key: string]: I18nCommonKey; +} = (isEdit: boolean) => { if (isEdit) { return { - title: 'Update DataBase', - applyBtnText: 'Update', - applyMessage: 'Confirm Update DataBase?', - applySuccess: 'Update Successful', - applyError: 'Update Failed' + title: 'update_database', + applyBtnText: 'update', + applyMessage: 'confirm_update_database', + applySuccess: 'update_successful', + applyError: 'update_failed' }; } return { - title: 'Deploy DataBase', - applyBtnText: 'Deploy', - applyMessage: 'Confirm Deploy DataBase?', - applySuccess: 'Deployment Successful', - applyError: 'Deployment Failed' + title: 'deploy_database', + applyBtnText: 'deploy', + applyMessage: 'confirm_deploy_database', + applySuccess: 'deployment_successful', + applyError: 'deployment_failed' }; }; diff --git a/frontend/providers/dbprovider/src/hooks/useConfirm.tsx b/frontend/providers/dbprovider/src/hooks/useConfirm.tsx index 4f6ad795295..22e834860b3 100644 --- a/frontend/providers/dbprovider/src/hooks/useConfirm.tsx +++ b/frontend/providers/dbprovider/src/hooks/useConfirm.tsx @@ -10,15 +10,16 @@ import { Button } from '@chakra-ui/react'; import { useTranslation } from 'next-i18next'; +import { I18nCommonKey } from '@/types/i18next'; export const useConfirm = ({ - title = 'Prompt', + title = 'prompt', content, - confirmText = 'Confirm' + confirmText = 'confirm' }: { - title?: string; - content: string; - confirmText?: string; + title?: I18nCommonKey; + content: I18nCommonKey; + confirmText?: I18nCommonKey; }) => { const { isOpen, onOpen, onClose } = useDisclosure(); const { t } = useTranslation(); @@ -46,7 +47,7 @@ export const useConfirm = ({ {t(title)} - {content} + {t(content)} diff --git a/frontend/providers/dbprovider/src/pages/db/detail/components/BackupModal.tsx b/frontend/providers/dbprovider/src/pages/db/detail/components/BackupModal.tsx index 9834f0aae16..e8bac66e5c0 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/components/BackupModal.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/components/BackupModal.tsx @@ -3,6 +3,7 @@ import Tip from '@/components/Tip'; import { DBBackupMethodNameMap, DBTypeEnum } from '@/constants/db'; import { useConfirm } from '@/hooks/useConfirm'; import type { AutoBackupFormType, AutoBackupType } from '@/types/backup'; +import { I18nCommonKey } from '@/types/i18next'; import { convertCronTime, getErrText } from '@/utils/tools'; import { InfoOutlineIcon } from '@chakra-ui/icons'; import { @@ -23,7 +24,7 @@ import { MySelect, Tabs, useMessage } from '@sealos/ui'; import { useMutation } from '@tanstack/react-query'; import { customAlphabet } from 'nanoid'; import { useTranslation } from 'next-i18next'; -import { useCallback, useRef, useState } from 'react'; +import { MutableRefObject, useCallback, useRef, useState } from 'react'; import { useForm } from 'react-hook-form'; const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6); @@ -50,15 +51,15 @@ const BackupModal = ({ const { message: toast } = useMessage(); const { openConfirm, ConfirmChild } = useConfirm({ - title: t('Confirm') || 'Confirm', - content: t('Manual Backup Tip'), - confirmText: 'Start Backup' + title: 'confirm', + content: 'manual_backup_tip', + confirmText: 'start_backup' }); const { openConfirm: CloseAutoBackup, ConfirmChild: AutoBackupConfirmChild } = useConfirm({ - title: 'Prompt', - content: t('Are you sure you want to turn off automatic backup'), - confirmText: 'Confirm' + title: 'prompt', + content: 'are_you_sure_you_want_to_turn_off_automatic_backup', + confirmText: 'confirm' }); const [refresh, setRefresh] = useState(false); @@ -97,7 +98,7 @@ const BackupModal = ({ }; }))() ); - const weekSelectList = useRef([ + const weekSelectList: MutableRefObject<{ label: I18nCommonKey; id: string }[]> = useRef([ { label: 'Monday', id: '1' }, { label: 'Tuesday', id: '2' }, { label: 'Wednesday', id: '3' }, @@ -139,7 +140,7 @@ const BackupModal = ({ onSuccess() { toast({ status: 'success', - title: t('The backup task has been created successfully !') + title: t('backup_success_tip') }); onClose(); }, @@ -183,7 +184,7 @@ const BackupModal = ({ onSuccess() { toast({ status: 'success', - title: t('Set auto backup successful') + title: t('set_auto_backup_successful') }); refetchPolicy(); onClose(); @@ -207,7 +208,7 @@ const BackupModal = ({ onSuccess() { toast({ status: 'success', - title: t('Automatic backup is turned off') + title: t('automatic_backup_is_turned_off') }); refetchPolicy(); onClose(); @@ -215,7 +216,7 @@ const BackupModal = ({ onError(err) { toast({ status: 'error', - title: t('Failed to turn off automatic backup') + title: t('failed_to_turn_off_automatic_backup') }); } }); @@ -236,11 +237,11 @@ const BackupModal = ({ borderRadius={'lg'} > - {t('Backup Database')} + {t('backup_database')} - {t('Manual Backup')} + {t('manual_backup')} - {t('Auto Backup')} + {t('auto_backup')} - {t(currentNav === 'auto' ? 'Auto Backup' : 'Manual Backup')} + {t(currentNav === 'auto' ? 'auto_backup' : 'manual_backup')} } size="sm" - text={t('Manual Backup Tip')} + text={t('manual_backup_tip')} /> {currentNav === NavEnum.manual && ( <> - {t('Backup Name')} + {t('backup_name')} @@ -302,7 +303,7 @@ const BackupModal = ({ variant={'solid'} onClick={() => handleSubmitManual(openConfirm(onclickBackup))()} > - {t('Start Backup')} + {t('start_backup')} @@ -355,7 +356,7 @@ const BackupModal = ({ )} {getAutoValues('type') !== 'hour' && ( - {t('Start Hour')} + {t('start_hour')} )} - {t('Start Minute')} + {t('start_minute')} (); @@ -114,7 +115,7 @@ const BackupTable = ({ db }: { db?: DBDetailType }, ref: ForwardedRef React.ReactNode | string; @@ -134,7 +135,7 @@ const BackupTable = ({ db }: { db?: DBDetailType }, ref: ForwardedRef ( - {t(item.status.label)} + {t(item.status.label as I18nCommonKey)} {item.failureReason && ( @@ -144,7 +145,7 @@ const BackupTable = ({ db }: { db?: DBDetailType }, ref: ForwardedRef <>{dayjs(item.startTime).format('YYYY/MM/DD HH:mm')} }, @@ -154,17 +155,17 @@ const BackupTable = ({ db }: { db?: DBDetailType }, ref: ForwardedRef <>{t(backupTypeMap[item.type]?.label) || '-'} }, { - title: 'Operation', + title: 'operation', key: 'control', render: (item: BackupItemType) => item.status.value !== BackupStatusEnum.InProgress ? ( - + - + )} @@ -141,7 +147,7 @@ const DelModal = ({ isLoading={loading} onClick={activePage === Page.REMINDER ? openTemplateApp : handleDelApp} > - {activePage === Page.REMINDER ? t('Confirm to go') : t('Confirm Delete')} + {activePage === Page.REMINDER ? t('confirm_to_go') : t('confirm_delete')} diff --git a/frontend/providers/dbprovider/src/pages/db/detail/components/DumpImport/index.tsx b/frontend/providers/dbprovider/src/pages/db/detail/components/DumpImport/index.tsx index bf43042ce74..32bf6793b58 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/components/DumpImport/index.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/components/DumpImport/index.tsx @@ -62,7 +62,7 @@ export default function DumpImport({ db }: { db?: DBDetailType }) { if (files.length <= 0) { closeMigrate(); return toast({ - title: t('Lost File'), + title: t('lost_file'), status: 'error' }); } @@ -74,16 +74,16 @@ export default function DumpImport({ db }: { db?: DBDetailType }) { if (!e.progress) return; const percent = Math.round(e.progress * 100); if (percent < 100) { - setFileProgressText(t('file.Uploading', { percent }) || ''); + setFileProgressText(t('file.Uploading', { percent })); } else { - setFileProgressText(t('file.Upload Success') || ''); + setFileProgressText(t('file.Upload Success')); } }); if (!result[0]) { closeMigrate(); return toast({ - title: t('File upload failed'), + title: t('file_upload_failed'), status: 'error' }); } @@ -101,7 +101,7 @@ export default function DumpImport({ db }: { db?: DBDetailType }) { (error) => { onClose(); const deepSearch = (obj: any): string => { - if (!obj) return t('Submit Error'); + if (!obj) return t('submit_error'); if (!!obj.message) { return obj.message; } @@ -204,34 +204,34 @@ export default function DumpImport({ db }: { db?: DBDetailType }) { - {t('Upload dump file')} + {t('upload_dump_file')} - {t('DB Name')} + {t('db_name')} {db?.dbType === 'mongodb' && ( - {t('Collection Name')} + {t('collection_name')} )} @@ -246,11 +246,11 @@ export default function DumpImport({ db }: { db?: DBDetailType }) { {migrateStatus === MigrateStatusEnum.Prepare && ( - {t('Prompt')} + {t('prompt')} - {t('Are you sure to perform database migration')} + {t('are_you_sure_to_perform_database_migration')} @@ -258,7 +258,7 @@ export default function DumpImport({ db }: { db?: DBDetailType }) { {t('Cancel')} @@ -287,7 +287,7 @@ export default function DumpImport({ db }: { db?: DBDetailType }) { {fileProgressText} - {t('Migration prompt information')} + {t('migration_prompt_information')} @@ -310,7 +310,7 @@ export default function DumpImport({ db }: { db?: DBDetailType }) { > - {t('Migration Successful')} + {t('migration_successful')} )} @@ -325,7 +325,7 @@ export default function DumpImport({ db }: { db?: DBDetailType }) { > - {t('Migration Failed')} + {t('migration_failed')} )} diff --git a/frontend/providers/dbprovider/src/pages/db/detail/components/Header.tsx b/frontend/providers/dbprovider/src/pages/db/detail/components/Header.tsx index f00b2563f7c..1e6c0852968 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/components/Header.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/components/Header.tsx @@ -31,10 +31,10 @@ const Header = ({ onClose: onCloseDelModal } = useDisclosure(); const { openConfirm: openRestartConfirm, ConfirmChild: RestartConfirmChild } = useConfirm({ - content: t('Confirm Restart') + content: t('confirm_restart') }); const { openConfirm: onOpenPause, ConfirmChild: PauseChild } = useConfirm({ - content: t('Pause Hint') + content: t('pause_hint') }); const [loading, setLoading] = useState(false); @@ -44,15 +44,12 @@ const Header = ({ setLoading(true); await restartDB(db); toast({ - title: 'Restart Success', + title: 'restart_success', status: 'success' }); } catch (error: any) { toast({ - title: - typeof error === 'string' - ? error - : error.message || t('Restart Error') || 'Restart Error', + title: typeof error === 'string' ? error : error.message || t('restart_error'), status: 'error' }); console.error(error); @@ -65,13 +62,12 @@ const Header = ({ setLoading(true); await pauseDBByName(db); toast({ - title: t('Pause Success') || 'Pause Success', + title: t('pause_success'), status: 'success' }); } catch (error: any) { toast({ - title: - typeof error === 'string' ? error : error.message || t('Pause Error') || 'Pause Error', + title: typeof error === 'string' ? error : error.message || t('pause_error'), status: 'error' }); console.error(error); @@ -84,13 +80,12 @@ const Header = ({ setLoading(true); await startDBByName(db); toast({ - title: t('Start Success') || 'Start Success', + title: t('start_success'), status: 'success' }); } catch (error: any) { toast({ - title: - typeof error === 'string' ? error : error.message || t('Start Error') || 'Start Error', + title: typeof error === 'string' ? error : error.message || t('start_error'), status: 'error' }); console.error(error); @@ -151,7 +146,7 @@ const Header = ({ router.push(`/db/edit?name=${db.dbName}`); }} > - {t('Update')} + {t('update')} )} {db.status.value === 'Stopped' ? ( diff --git a/frontend/providers/dbprovider/src/pages/db/detail/components/Migrate/Table.tsx b/frontend/providers/dbprovider/src/pages/db/detail/components/Migrate/Table.tsx index 3bf245a179f..99c6ead5175 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/components/Migrate/Table.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/components/Migrate/Table.tsx @@ -23,6 +23,7 @@ import { useTranslation } from 'next-i18next'; import React, { useCallback, useState } from 'react'; import LogsModal from './LogsModal'; import MigrateStatus from './MigrateStatus'; +import { I18nCommonKey } from '@/types/i18next'; export const MigrateTable = ({ dbName }: { dbName: string }) => { if (!dbName) return <>; @@ -53,7 +54,7 @@ export const MigrateTable = ({ dbName }: { dbName: string }) => { ); const { openConfirm: openConfirmDel, ConfirmChild: ConfirmDelChild } = useConfirm({ - content: t('Confirm delete the migrate') + content: t('confirm_delete_the_migrate') }); const confirmDel = useCallback( @@ -78,7 +79,7 @@ export const MigrateTable = ({ dbName }: { dbName: string }) => { }; const columns: { - title: string; + title: I18nCommonKey; dataIndex?: keyof MigrateItemType; key: string; render?: (item: MigrateItemType, i: number) => React.ReactNode | string; @@ -101,12 +102,12 @@ export const MigrateTable = ({ dbName }: { dbName: string }) => { ) }, { - title: 'Creation Time', + title: 'creation_time', key: 'creationtime', render: (item: MigrateItemType) => <>{dayjs(item.startTime).format('YYYY/MM/DD HH:mm')} }, { - title: 'Operation', + title: 'operation', key: 'control', render: (item: MigrateItemType) => { return ( @@ -173,7 +174,7 @@ export const MigrateTable = ({ dbName }: { dbName: string }) => { {isSuccess && migrateList.length === 0 && ( - {t('No Data Available')} + {t('no_data_available')} )} diff --git a/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/ChartTemplate.tsx b/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/ChartTemplate.tsx index 10e8a41984d..7ad087494a8 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/ChartTemplate.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/ChartTemplate.tsx @@ -90,7 +90,7 @@ const ChartTemplate = ({ - {t('No Data Available')} + {t('no_data_available')} )} diff --git a/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/RunningTime.tsx b/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/RunningTime.tsx index 55c8c427f07..ef4f9cfb5bb 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/RunningTime.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/RunningTime.tsx @@ -54,12 +54,12 @@ const RunningTime = ({ border={'1px solid #CCEEED'} backgroundColor={'rgba(0, 169, 166, 0.07)'} > - {t('Running Time')} + {t('running_time')} {MaxTime?.time} - {t(MaxTime?.unit || '')} + {t(MaxTime?.unit || 'start_minute')} - {t('InnoDB Buffer Pool')} + {t('innodb_buffer_pool')} {MysqlInnoDB?.result?.value} @@ -99,12 +99,12 @@ const RunningTime = ({ border={'1px solid #CCEEED'} backgroundColor={'rgba(0, 169, 166, 0.07)'} > - {t('Running Time')} + {t('running_time')} {MaxTime?.time} - {t(MaxTime?.unit || '')} + {t(MaxTime?.unit || 'start_minute')} ); }; diff --git a/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/index.tsx b/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/index.tsx index 57afb2e6f0b..1cd82ccbb0d 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/index.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/components/Monitor/index.tsx @@ -46,14 +46,14 @@ const Monitor = ({ db, dbName, dbType }: { dbName: string; dbType: string; db?: onChange={(id) => setActiveId(id as MonitorType)} /> - {t('Update Time')} {currentTime} + {t('update_time')} {currentTime} {activeId === MonitorType.resources && ( } onClick={onclickAnalyses} > - {t('Event Analyze')} + {t('event_analyze')} )} */} diff --git a/frontend/providers/dbprovider/src/pages/db/detail/components/Pods.tsx b/frontend/providers/dbprovider/src/pages/db/detail/components/Pods.tsx index a1b49410f95..6602e75f1d9 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/components/Pods.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/components/Pods.tsx @@ -5,6 +5,7 @@ import { useConfirm } from '@/hooks/useConfirm'; import { useLoading } from '@/hooks/useLoading'; import { useDBStore } from '@/store/db'; import type { PodDetailType } from '@/types/db'; +import { I18nCommonKey } from '@/types/i18next'; import { Box, Button, @@ -33,7 +34,7 @@ const Pods = ({ dbName, dbType }: { dbName: string; dbType: string }) => { const [detailPodIndex, setDetailPodIndex] = useState(); const { Loading } = useLoading(); const { openConfirm: openConfirmRestart, ConfirmChild: RestartConfirmChild } = useConfirm({ - content: t('Confirm Restart Pod') || 'Confirm Restart Pod' + content: t('confirm_restart_pod') }); const { intervalLoadPods, dbPods } = useDBStore(); @@ -47,7 +48,7 @@ const Pods = ({ dbName, dbType }: { dbName: string; dbType: string }) => { }); } catch (err) { toast({ - title: `${t('Restart')} ${podName} ${t('Have Error')}`, + title: `${t('Restart')} ${podName} ${t('have_error')}`, status: 'warning' }); } @@ -57,7 +58,7 @@ const Pods = ({ dbName, dbType }: { dbName: string; dbType: string }) => { // console.log(dbPods); const columns: { - title: string; + title: I18nCommonKey; dataIndex?: keyof PodDetailType; key: string; render?: (item: PodDetailType, i: number) => JSX.Element | string; @@ -73,17 +74,17 @@ const Pods = ({ dbName, dbType }: { dbName: string; dbType: string }) => { render: (item: PodDetailType) => }, { - title: 'Restarts', + title: 'restarts', key: 'restarts', dataIndex: 'restarts' }, { - title: 'Age', + title: 'age', key: 'age', dataIndex: 'age' }, { - title: 'Operation', + title: 'operation', key: 'control', render: (item: PodDetailType, i: number) => ( diff --git a/frontend/providers/dbprovider/src/pages/db/detail/components/RestoreModal.tsx b/frontend/providers/dbprovider/src/pages/db/detail/components/RestoreModal.tsx index c75c789e16e..b42b603f5d9 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/components/RestoreModal.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/components/RestoreModal.tsx @@ -61,7 +61,7 @@ const RestoreModal = ({ router.replace(`/dbs`); toast({ status: 'success', - title: t('Restore Success') + title: t('restore_success') }); onClose(); }, @@ -80,22 +80,22 @@ const RestoreModal = ({ - {t('Restore Database')} + {t('restore_database')} } size="sm" - text={t('Restore Backup Tip')} + text={t('restore_backup_tip')} borderRadius={'md'} /> - {t('Database Name')} + {t('database_name')} diff --git a/frontend/providers/dbprovider/src/pages/db/detail/index.tsx b/frontend/providers/dbprovider/src/pages/db/detail/index.tsx index 7edffb81ea2..e6be30acee4 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/index.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/index.tsx @@ -17,6 +17,7 @@ import Header from './components/Header'; import MigrateTable from './components/Migrate/Table'; import Monitor from './components/Monitor'; import Pods from './components/Pods'; +import { I18nCommonKey } from '@/types/i18next'; enum TabEnum { pod = 'pod', @@ -48,12 +49,12 @@ const AppDetail = ({ SystemEnv.BACKUP_ENABLED; const listNavValue = [ - { label: 'Monitor List', value: TabEnum.monitor }, - { label: 'Replicas List', value: TabEnum.pod }, - ...(BackupSupported ? [{ label: 'Backup List', value: TabEnum.backup }] : []), - ...(PublicNetMigration ? [{ label: 'Online Import', value: TabEnum.InternetMigration }] : []), + { label: 'monitor_list', value: TabEnum.monitor }, + { label: 'replicas_list', value: TabEnum.pod }, + ...(BackupSupported ? [{ label: 'backup_list', value: TabEnum.backup }] : []), + ...(PublicNetMigration ? [{ label: 'online_import', value: TabEnum.InternetMigration }] : []), ...(PublicNetMigration && !!SystemEnv.minio_url - ? [{ label: 'Import Through File', value: TabEnum.DumpImport }] + ? [{ label: 'import_through_file', value: TabEnum.DumpImport }] : []) ]; @@ -144,7 +145,7 @@ const AppDetail = ({ ) })} > - {t(item.label)} + {t(item.label as I18nCommonKey)} ))} diff --git a/frontend/providers/dbprovider/src/pages/db/edit/components/Form.tsx b/frontend/providers/dbprovider/src/pages/db/edit/components/Form.tsx index 4340a08d974..005d0a31626 100644 --- a/frontend/providers/dbprovider/src/pages/db/edit/components/Form.tsx +++ b/frontend/providers/dbprovider/src/pages/db/edit/components/Form.tsx @@ -31,6 +31,7 @@ import { useRouter } from 'next/router'; import { useEffect, useMemo, useState } from 'react'; import { UseFormReturn } from 'react-hook-form'; import PriceBox from '@/components/PriceBox'; +import { I18nCommonKey } from '@/types/i18next'; const Form = ({ formHook, @@ -55,10 +56,10 @@ const Form = ({ formState: { errors } } = formHook; - const navList = [ + const navList: { id: string; label: I18nCommonKey; icon: string }[] = [ { id: 'baseInfo', - label: t('Basic'), + label: 'basic', icon: 'formInfo' } ]; @@ -143,8 +144,8 @@ const Form = ({ @@ -237,7 +238,7 @@ const Form = ({ - {t('Basic')} + {t('basic')} @@ -297,11 +298,11 @@ const Form = ({ - + ({ label: i.label, @@ -315,14 +316,14 @@ const Form = ({ @@ -345,7 +346,7 @@ const Form = ({ - + { register('replicas', { - required: t('Replicas Cannot Empty') || '', + required: t('replicas_cannot_empty'), min: { value: 1, - message: `${t('Min Replicas')}1` + message: `${t('min_replicas')}1` }, max: { value: 20, - message: `${t('Max Replicas')}20` + message: `${t('max_replicas')}20` } }); const dbType = getValues('dbType'); @@ -394,7 +395,7 @@ const Form = ({ } - text="The Single-node database is only suitable for development testing" + text={t('single_node_tip')} size="sm" borderRadius={'md'} /> @@ -403,7 +404,7 @@ const Form = ({ } - text="The multi-replica Redis includes High Availability (HA) nodes, Please note, the anticipated price already encompasses the cost for the HA nodes" + text={t('multi_replica_redis_tip')} size="sm" borderRadius={'md'} /> @@ -414,7 +415,7 @@ const Form = ({ } - text={t('db instances tip', { + text={t('db_instances_tip', { db: getValues('dbType') })} size="sm" @@ -425,8 +426,8 @@ const Form = ({ - - + + void; - applyBtnText: string; + applyBtnText: I18nCommonKey; }) => { const { t } = useTranslation(); const router = useRouter(); diff --git a/frontend/providers/dbprovider/src/pages/db/edit/components/Yaml.tsx b/frontend/providers/dbprovider/src/pages/db/edit/components/Yaml.tsx index 6b49472da58..15afc3d07f1 100644 --- a/frontend/providers/dbprovider/src/pages/db/edit/components/Yaml.tsx +++ b/frontend/providers/dbprovider/src/pages/db/edit/components/Yaml.tsx @@ -29,8 +29,8 @@ const Yaml = ({ yamlList = [], pxVal }: { yamlList: YamlItemType[]; pxVal: numbe diff --git a/frontend/providers/dbprovider/src/pages/db/edit/index.tsx b/frontend/providers/dbprovider/src/pages/db/edit/index.tsx index fa6ac3601eb..62cb663e296 100644 --- a/frontend/providers/dbprovider/src/pages/db/edit/index.tsx +++ b/frontend/providers/dbprovider/src/pages/db/edit/index.tsx @@ -136,7 +136,7 @@ const EditApp = ({ dbName, tabType }: { dbName?: string; tabType?: 'form' | 'yam const submitError = useCallback(() => { // deep search message const deepSearch = (obj: any): string => { - if (!obj || typeof obj !== 'object') return t('Submit Error'); + if (!obj || typeof obj !== 'object') return t('submit_error'); if (!!obj.message) { return obj.message; } diff --git a/frontend/providers/dbprovider/src/pages/db/migrate/components/Form.tsx b/frontend/providers/dbprovider/src/pages/db/migrate/components/Form.tsx index 97341c597aa..6aab5dc7a4a 100644 --- a/frontend/providers/dbprovider/src/pages/db/migrate/components/Form.tsx +++ b/frontend/providers/dbprovider/src/pages/db/migrate/components/Form.tsx @@ -27,6 +27,7 @@ import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; import { UseFormReturn } from 'react-hook-form'; import PrepareBox from './Prepare'; +import { I18nCommonKey } from '@/types/i18next'; const Form = ({ formHook, @@ -51,20 +52,20 @@ const Form = ({ formState: { errors } } = formHook; - const navList = [ + const navList: { id: string; label: I18nCommonKey; icon: string }[] = [ { id: 'preparation', - label: t('Migration Preparation'), + label: t('migration_preparation'), icon: 'book' }, { id: 'baseInfo', - label: t('Basic'), + label: t('basic'), icon: 'formInfo' }, { id: 'settings', - label: t('Advanced Configuration'), + label: t('advanced_configuration'), icon: 'settings' } ]; @@ -148,8 +149,8 @@ const Form = ({ { @@ -214,11 +215,11 @@ const Form = ({ position={'relative'} overflowY={'scroll'} > - {/* Migration Preparation */} + {/* migration_preparation */} - {t('Migration Preparation')} + {t('migration_preparation')} @@ -228,19 +229,19 @@ const Form = ({ - {t('Basic')} + {t('basic')} - {t('Source Database')} + {t('source_database')} - + @@ -249,9 +250,9 @@ const Form = ({ @@ -260,9 +261,9 @@ const Form = ({ @@ -271,27 +272,27 @@ const Form = ({ - + - + { @@ -303,7 +304,7 @@ const Form = ({ - + @@ -320,7 +321,7 @@ const Form = ({ > - {t('Advanced Configuration')} + {t('advanced_configuration')}
- {t('Continuous Migration')} + {t('continuous_migration')} diff --git a/frontend/providers/dbprovider/src/pages/db/migrate/components/Header.tsx b/frontend/providers/dbprovider/src/pages/db/migrate/components/Header.tsx index 57e61795783..0c64b509677 100644 --- a/frontend/providers/dbprovider/src/pages/db/migrate/components/Header.tsx +++ b/frontend/providers/dbprovider/src/pages/db/migrate/components/Header.tsx @@ -1,5 +1,6 @@ import MyIcon from '@/components/Icon'; import { DBType } from '@/types/db'; +import { I18nCommonKey } from '@/types/i18next'; import { Box, Button, Flex } from '@chakra-ui/react'; import { useTranslation } from 'next-i18next'; import { useRouter } from 'next/router'; @@ -12,10 +13,10 @@ const Header = ({ applyBtnText }: { dbName: string; - title: string; + title: I18nCommonKey; dbType: DBType; applyCb: () => void; - applyBtnText: string; + applyBtnText: I18nCommonKey; }) => { const { t } = useTranslation(); const router = useRouter(); diff --git a/frontend/providers/dbprovider/src/pages/db/migrate/components/Prepare.tsx b/frontend/providers/dbprovider/src/pages/db/migrate/components/Prepare.tsx index d6ac390ac7b..c63b537fcfc 100644 --- a/frontend/providers/dbprovider/src/pages/db/migrate/components/Prepare.tsx +++ b/frontend/providers/dbprovider/src/pages/db/migrate/components/Prepare.tsx @@ -35,13 +35,13 @@ export default function PrepareBox({ "show variables like '%row_im%'; ", "set binlog_row_image ='FULL'; " ], - checkboxLabel: t('I have read and completed migration preparations'), + checkboxLabel: t('migration_preparations'), permissionCheck: `source account: REPLICATION SLAVE、REPLICATION CLIENT、SELECT \nsink account: SELECT、INSERT、UPDATE、DELETE、CREATE、ALTER、DROP`, title: 'MySQL' }, mongodb: { codeList: [t('migrate.mongodb.stepOne'), t('migrate.mongodb.stepTwo')], - checkboxLabel: t('I have read and completed migration preparations'), + checkboxLabel: t('migration_preparations'), permissionCheck: t('migrate.mongo.check'), title: 'Monogo' }, @@ -52,7 +52,7 @@ export default function PrepareBox({ `ALTER SYSTEM SET wal_level = 'logical';`, t('migrate.postgresql.stepTwo') ], - checkboxLabel: t('I have read and completed migration preparations'), + checkboxLabel: t('migration_preparations'), permissionCheck: t('migrate.postgresql.check'), title: 'PostgreSQL' } @@ -64,7 +64,7 @@ export default function PrepareBox({ return ( - {content.title} {t('Migrate Config')} + {content.title} {t('migrate_config')} - {content.title} {t('Migration Permission Check')} + {content.title} {t('migration_permission_check')} {content.permissionCheck} - {t('Covering Risks')} + {t('covering_risks')} - {t('Important tips for migrating')} + {t('important_tips_for_migrating')} diff --git a/frontend/providers/dbprovider/src/pages/db/migrate/index.tsx b/frontend/providers/dbprovider/src/pages/db/migrate/index.tsx index 909211edd6f..58b25171912 100644 --- a/frontend/providers/dbprovider/src/pages/db/migrate/index.tsx +++ b/frontend/providers/dbprovider/src/pages/db/migrate/index.tsx @@ -58,7 +58,7 @@ const EditApp = ({ const { Loading, setIsLoading } = useLoading(); const { checkQuotaAllow, balance } = useUserStore(); const { openConfirm, ConfirmChild } = useConfirm({ - content: t('Are you sure to perform database migration') + content: t('are_you_sure_to_perform_database_migration') }); const { loadDBDetail } = useDBStore(); const { screenWidth, lastRoute } = useGlobalStore(); @@ -121,7 +121,7 @@ const EditApp = ({ } await applyYamlList(yamlList, 'create'); toast({ - title: t('Migration task created successfully'), + title: t('migration_task_created_successfully'), status: 'success' }); router.push({ @@ -140,13 +140,13 @@ const EditApp = ({ const submitError = useCallback(() => { const deepSearch = (obj: any, depth: number = 2): string => { - if (!obj || depth === 0) return t('Submit Error'); + if (!obj || depth === 0) return t('submit_error'); if (!!obj.message) { return obj.message; } const values = Object.values(obj); if (values.length === 0 || typeof values[0] !== 'object') { - return t('Submit Error'); + return t('submit_error'); } return deepSearch(values[0], depth - 1); }; @@ -214,8 +214,8 @@ const EditApp = ({
formHook.handleSubmit((data) => openConfirm(() => submitSuccess(data))(), submitError)() } diff --git a/frontend/providers/dbprovider/src/pages/dbs/components/dbList.tsx b/frontend/providers/dbprovider/src/pages/dbs/components/dbList.tsx index 5af57cb9562..c29cc37453f 100644 --- a/frontend/providers/dbprovider/src/pages/dbs/components/dbList.tsx +++ b/frontend/providers/dbprovider/src/pages/dbs/components/dbList.tsx @@ -32,7 +32,7 @@ const DBList = ({ const [delAppName, setDelAppName] = useState(''); const { openConfirm: onOpenPause, ConfirmChild: PauseChild } = useConfirm({ - content: t('Pause Hint') + content: t('pause_hint') }); const handleRestartApp = useCallback( @@ -41,12 +41,12 @@ const DBList = ({ setLoading(true); await restartDB({ dbName: db.name, dbType: db.dbType }); toast({ - title: t('Restart Success'), + title: t('restart_success'), status: 'success' }); } catch (error: any) { toast({ - title: typeof error === 'string' ? error : error.message || t('Restart Success'), + title: typeof error === 'string' ? error : error.message || t('restart_success'), status: 'error' }); console.error(error, '=='); @@ -62,12 +62,12 @@ const DBList = ({ setLoading(true); await pauseDBByName({ dbName: db.name, dbType: db.dbType }); toast({ - title: t('Pause Success'), + title: t('pause_success'), status: 'success' }); } catch (error: any) { toast({ - title: typeof error === 'string' ? error : error.message || t('Pause Error'), + title: typeof error === 'string' ? error : error.message || t('pause_error'), status: 'error' }); console.error(error); @@ -84,12 +84,12 @@ const DBList = ({ setLoading(true); await startDBByName({ dbName: db.name, dbType: db.dbType }); toast({ - title: t('Start Success'), + title: t('start_success'), status: 'success' }); } catch (error: any) { toast({ - title: typeof error === 'string' ? error : error.message || t('Start Error'), + title: typeof error === 'string' ? error : error.message || t('start_error'), status: 'error' }); console.error(error); @@ -135,27 +135,27 @@ const DBList = ({ ) }, { - title: t('Creation Time'), + title: t('creation_time'), dataIndex: 'createTime', key: 'createTime' }, { - title: t('CPU'), + title: t('cpu'), key: 'cpu', render: (item: DBListItemType) => <>{item.cpu / 1000}C }, { - title: t('Memory'), + title: t('memory'), key: 'memory', render: (item: DBListItemType) => <>{printMemory(item.memory)} }, { - title: t('Storage'), + title: t('storage'), key: 'storage', dataIndex: 'storage' }, { - title: t('Operation'), + title: t('operation'), key: 'control', render: (item: DBListItemType) => ( @@ -199,7 +199,7 @@ const DBList = ({ child: ( <> - {t('Update')} + {t('update')} ), onClick: () => router.push(`/db/edit?name=${item.name}`), @@ -282,7 +282,7 @@ const DBList = ({ leftIcon={} onClick={() => window.open('https://sealos.run/docs/guides/dbprovider/')} > - {t('Use Docs')} + {t('use_docs')} )} diff --git a/frontend/providers/dbprovider/src/pages/dbs/components/empty.tsx b/frontend/providers/dbprovider/src/pages/dbs/components/empty.tsx index 6976f239613..794a6713312 100644 --- a/frontend/providers/dbprovider/src/pages/dbs/components/empty.tsx +++ b/frontend/providers/dbprovider/src/pages/dbs/components/empty.tsx @@ -18,9 +18,9 @@ const Empty = () => { bg={'#F3F4F5'} > - {t('DataBase Empty')} + {t('database_empty')} ); diff --git a/frontend/providers/dbprovider/src/store/user.ts b/frontend/providers/dbprovider/src/store/user.ts index 09056807fd8..ac77b3bbd39 100644 --- a/frontend/providers/dbprovider/src/store/user.ts +++ b/frontend/providers/dbprovider/src/store/user.ts @@ -1,5 +1,6 @@ import { getUserQuota } from '@/api/platform'; import { DBEditType } from '@/types/db'; +import { I18nCommonKey } from '@/types/i18next'; import { UserQuotaItemType } from '@/types/user'; import { create } from 'zustand'; import { devtools } from 'zustand/middleware'; @@ -9,7 +10,7 @@ type State = { balance: number; userQuota: UserQuotaItemType[]; loadUserQuota: () => Promise; - checkQuotaAllow: (request: DBEditType, usedData?: DBEditType) => string; + checkQuotaAllow: (request: DBEditType, usedData?: DBEditType) => I18nCommonKey; }; export const useUserStore = create()( @@ -25,7 +26,7 @@ export const useUserStore = create()( }); return null; }, - checkQuotaAllow: ({ cpu, memory, storage, replicas }, usedData) => { + checkQuotaAllow: ({ cpu, memory, storage, replicas }, usedData): I18nCommonKey => { const quote = get().userQuota; const request = { @@ -41,10 +42,10 @@ export const useUserStore = create()( request.storage -= storage * replicas; } - const overLimitTip = { - cpu: 'app.The applied CPU exceeds the quota', - memory: 'app.The applied memory exceeds the quota', - storage: 'app.The applied storage exceeds the quota' + const overLimitTip: { [key: string]: I18nCommonKey } = { + cpu: 'app.cpu_exceeds_quota', + memory: 'app.memory_exceeds_quota', + storage: 'app.storage_exceeds_quota' }; const exceedQuota = quote.find((item) => { @@ -53,7 +54,7 @@ export const useUserStore = create()( } }); - return exceedQuota?.type ? overLimitTip[exceedQuota.type] : ''; + return exceedQuota?.type ? overLimitTip[exceedQuota.type] : 'app.cpu_exceeds_quota'; } })) ) diff --git a/frontend/providers/dbprovider/src/types/i18next.d.ts b/frontend/providers/dbprovider/src/types/i18next.d.ts new file mode 100644 index 00000000000..f42b7f18d7e --- /dev/null +++ b/frontend/providers/dbprovider/src/types/i18next.d.ts @@ -0,0 +1,32 @@ +import 'i18next'; +import common from '../../public/locales/zh/common.json'; + +export interface I18nNamespaces { + common: typeof common; +} + +export type I18nNsType = (keyof I18nNamespaces)[]; + +export type NestedKeyOf = { + [Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object + ? `${Key}.${NestedKeyOf}` + : `${Key}`; +}[keyof ObjectType & (string | number)]; + +export type ParseKeys = { + [K in Ns]: `${K}:${NestedKeyOf}`; +}[Ns]; + +export type I18nKeyFunction = { + (key: Key): Key; +}; + +export type I18nCommonKey = NestedKeyOf; + +declare module 'i18next' { + interface CustomTypeOptions { + returnNull: false; + defaultNS: ['common']; + resources: I18nNamespaces; + } +} diff --git a/frontend/providers/dbprovider/src/types/monitor.d.ts b/frontend/providers/dbprovider/src/types/monitor.d.ts index 484dfd570a5..a67143dd9d0 100644 --- a/frontend/providers/dbprovider/src/types/monitor.d.ts +++ b/frontend/providers/dbprovider/src/types/monitor.d.ts @@ -1,3 +1,5 @@ +import { I18nCommonKey } from './i18next'; + export interface MonitorDBResult { status: string; data: { @@ -56,7 +58,7 @@ export type ChartTemplateProps = { dbName: string; dbType: string; apiUrl: string; - chartTitle: string; + chartTitle: I18nCommonKey; isShowLegend?: boolean; db?: DBDetailType; queryKey?: keyof MonitorQueryKey; diff --git a/frontend/providers/dbprovider/src/utils/tools.ts b/frontend/providers/dbprovider/src/utils/tools.ts index e19acf02a55..11fbdb44549 100644 --- a/frontend/providers/dbprovider/src/utils/tools.ts +++ b/frontend/providers/dbprovider/src/utils/tools.ts @@ -1,3 +1,4 @@ +import { I18nCommonKey } from '@/types/i18next'; import { useMessage } from '@sealos/ui'; import { addHours, format, set, startOfDay } from 'date-fns'; import dayjs from 'dayjs'; @@ -15,7 +16,7 @@ export const useCopyData = () => { const { t } = useTranslation(); return { - copyData: (data: string, title: string = 'Copy Success') => { + copyData: (data: string, title: I18nCommonKey = 'copy_success') => { try { const textarea = document.createElement('textarea'); textarea.value = data; @@ -31,7 +32,7 @@ export const useCopyData = () => { } catch (error) { console.error(error); toast({ - title: t('Copy Failed'), + title: t('copy_failed'), status: 'error' }); } @@ -266,7 +267,7 @@ export const convertBytes = (bytes: number, unit: 'kb' | 'mb' | 'gb' | 'tb') => }; // formatTime second to day, hour or minute -export const formatTimeToDay = (seconds: number): { time: string; unit: string } => { +export const formatTimeToDay = (seconds: number): { time: string; unit: I18nCommonKey } => { const minutes = Math.floor(seconds / 60); const hours = Math.floor(seconds / 3600); const days = Math.floor(seconds / (3600 * 24)); @@ -283,7 +284,7 @@ export const formatTimeToDay = (seconds: number): { time: string; unit: string } }; } else { return { - unit: 'Start Minute', + unit: 'start_minute', time: (seconds / 60).toFixed(1) }; }