Localize database-config, snapshots panel and new-service wizard.

Add components.dbConfig / components.snapshots and dashboard.servicesNew
dictionaries; move the managed-database config (engine, credentials, dump
upload, storage), the snapshots panel and the three-step new-service
wizard onto them. validateDbDumpStorage now takes a localized template.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
keyhan
2026-06-11 19:22:37 +03:30
parent 63e368f464
commit 96d24b50a1
6 changed files with 334 additions and 114 deletions
+103
View File
@@ -252,6 +252,69 @@ const en: Dictionary = {
mShort: 'm',
sShort: 's',
},
dbConfig: {
engine: 'Database engine',
version: 'Version',
credentials: 'Database credentials',
credentialsOptional: '(optional — auto-generated if empty)',
username: 'Username',
usernamePlaceholder: 'appuser',
password: 'Password',
passwordPlaceholder: 'Auto-generated',
generatePassword: 'Generate random password',
credentialsNote: 'Used for internal cluster access. Use temporary or permanent external access below after deploy.',
uploadDumpLabel: 'Optional: upload DB dump to restore at creation',
remove: 'Remove',
uploadHint: 'Upload a SQL dump to be restored after the database is created',
uploadConstraints: 'Optional • Max 500MB • .sql, .gz, .dump',
allowedFormats: 'Allowed: .sql, .gz, .dump',
maxSize: 'Max 500MB',
storageSize: 'Database storage size',
suggestedFromDump: 'Suggested from dump ({gi} GiB min fit)',
minimumGb: 'Minimum {n} GB',
mustFitDump: ' (must fit the uploaded dump)',
expansionOnly: ' • Only expansion allowed after creation',
storageTooSmallTitle: 'Storage too small',
ok: 'OK',
storageTooSmallDetail: 'Your database dump is about {dumpGi} GiB. Database storage must be at least {need} GiB (you selected {selected} GiB). Increase database storage, then try again.',
},
snapshots: {
title: 'Snapshots',
newSnapshot: 'New Snapshot',
creating: 'Creating…',
hide: 'Hide',
show: 'Show',
deployFirst: 'Deploy the service first',
waitCurrent: 'Wait for the current backup to finish',
infoNote: 'Database snapshots store a SQL dump you can download later. When progress reaches 100%, use the download button. Up to 10 snapshots are kept; oldest are removed automatically.',
loadingBackups: 'Loading backups…',
noBackups: 'No backups yet',
noBackupsHint: 'Click New backup to create your first database dump.',
defaultLabel: 'Database backup',
auto: 'Auto',
manual: 'Manual',
dumping: 'Dumping…',
preparing: 'Preparing dump…',
exporting: 'Exporting database…',
finalizing: 'Finalizing…',
creatingDump: 'Creating database dump…',
dump: 'Dump',
downloadTitle: 'Download database dump',
deleteTitle: 'Delete backup',
removeFailedTitle: 'Remove failed backup',
maxKept: 'Maximum 10 backups are kept.',
backupReady: 'Backup ready — you can download the dump now',
backupFailed: 'Backup failed',
backupStarted: 'Backup started — dump in progress',
createFailed: 'Failed to create backup',
backupDeleted: 'Backup deleted',
deleteFailed: 'Failed to delete backup',
downloadStarted: 'Download started',
downloadFailed: 'Failed to download database dump',
deleteConfirmTitle: 'Delete backup?',
deleteConfirmMessage: 'Delete “{label}”? The dump file will be permanently removed.',
snapStatus: { completed: 'completed', failed: 'failed' },
},
},
nav: {
@@ -802,6 +865,46 @@ const en: Dictionary = {
hours: 'hours',
days: 'days',
},
servicesNew: {
steps: ['Service type', 'Configuration', 'Review & pay'],
title: 'New managed service',
subtitle: 'Database, Redis, or RabbitMQ — billed like applications',
typeDatabase: 'Database',
typeDatabaseDesc: 'PostgreSQL, MySQL, MariaDB, MongoDB',
typeRedis: 'Redis',
typeRedisDesc: 'In-memory cache & store',
typeRabbitmq: 'RabbitMQ',
typeRabbitmqDesc: 'Message broker',
serviceName: 'Service name',
serviceNamePlaceholder: 'my-database',
nameHint: 'Lowercase letters, numbers, and hyphens only',
redisVersion: 'Redis version',
rabbitmqVersion: 'RabbitMQ version',
redisResources: 'Redis resources',
rabbitmqResources: 'RabbitMQ resources',
billingCycle: 'Billing cycle',
cycles: { hourly: 'Hourly', monthly: 'Monthly', yearly: 'Yearly' },
paymentMethod: 'Payment method',
wallet: 'Wallet',
insufficient: 'Insufficient',
payNow: 'Pay now',
pricingUnavailable: 'Pricing unavailable',
back: 'Back',
next: 'Next',
payProvision: 'Pay & provision',
provisioning: 'Provisioning service',
creatingService: 'Creating service',
uploadingDump: 'Uploading database dump',
payment: 'Payment',
deploying: 'Deploying',
provisionedSuccess: 'Service provisioned successfully',
deployFailed: 'Deploy failed',
paySucceededDeployFailed: 'Payment succeeded but deployment failed',
payProvisionFailed: 'Payment or provisioning failed',
payFailed: 'Payment failed',
insufficientBalance: 'Insufficient wallet balance',
serviceDesc: 'Service: {name} ({cycle})',
},
},
};
+103
View File
@@ -251,6 +251,69 @@ const fa = {
mShort: 'د',
sShort: 'ث',
},
dbConfig: {
engine: 'موتور دیتابیس',
version: 'نسخه',
credentials: 'اطلاعات ورود دیتابیس',
credentialsOptional: '(اختیاری — اگر خالی باشد خودکار ساخته می‌شود)',
username: 'نام کاربری',
usernamePlaceholder: 'appuser',
password: 'رمز عبور',
passwordPlaceholder: 'تولید خودکار',
generatePassword: 'تولید رمز تصادفی',
credentialsNote: 'برای دسترسی داخلی کلاستر استفاده می‌شود. پس از انتشار از دسترسی خارجی موقت یا دائمی زیر استفاده کن.',
uploadDumpLabel: 'اختیاری: آپلود dump دیتابیس برای بازیابی هنگام ساخت',
remove: 'حذف',
uploadHint: 'یک SQL dump آپلود کن تا پس از ساخت دیتابیس بازیابی شود',
uploadConstraints: 'اختیاری • حداکثر ۵۰۰ مگابایت • .sql, .gz, .dump',
allowedFormats: 'مجاز: .sql، .gz، .dump',
maxSize: 'حداکثر ۵۰۰ مگابایت',
storageSize: 'اندازهٔ فضای ذخیرهٔ دیتابیس',
suggestedFromDump: 'پیشنهادشده از dump (حداقل {gi} GiB)',
minimumGb: 'حداقل {n} GB',
mustFitDump: ' (باید dump آپلودشده را جا دهد)',
expansionOnly: ' • فقط افزایش پس از ساخت مجاز است',
storageTooSmallTitle: 'فضای ذخیره خیلی کم است',
ok: 'باشه',
storageTooSmallDetail: 'حجم dump دیتابیس شما حدود {dumpGi} GiB است. فضای ذخیرهٔ دیتابیس باید حداقل {need} GiB باشد (شما {selected} GiB انتخاب کردی). فضای ذخیره را افزایش بده و دوباره تلاش کن.',
},
snapshots: {
title: 'اسنپ‌شات‌ها',
newSnapshot: 'اسنپ‌شات جدید',
creating: 'در حال ساخت…',
hide: 'پنهان',
show: 'نمایش',
deployFirst: 'اول سرویس را منتشر کن',
waitCurrent: 'منتظر پایان بکاپ فعلی بمان',
infoNote: 'اسنپ‌شات‌های دیتابیس یک SQL dump ذخیره می‌کنند که بعداً می‌توانی دانلود کنی. وقتی پیشرفت به ۱۰۰٪ رسید از دکمهٔ دانلود استفاده کن. تا ۱۰ اسنپ‌شات نگه داشته می‌شود؛ قدیمی‌ترها خودکار حذف می‌شوند.',
loadingBackups: 'در حال بارگذاری بکاپ‌ها…',
noBackups: 'هنوز بکاپی نیست',
noBackupsHint: 'برای ساخت اولین dump دیتابیس روی «اسنپ‌شات جدید» بزن.',
defaultLabel: 'بکاپ دیتابیس',
auto: 'خودکار',
manual: 'دستی',
dumping: 'در حال dump…',
preparing: 'آماده‌سازی dump…',
exporting: 'استخراج دیتابیس…',
finalizing: 'نهایی‌سازی…',
creatingDump: 'ساخت dump دیتابیس…',
dump: 'dump',
downloadTitle: 'دانلود dump دیتابیس',
deleteTitle: 'حذف بکاپ',
removeFailedTitle: 'حذف بکاپ ناموفق',
maxKept: 'حداکثر ۱۰ بکاپ نگه داشته می‌شود.',
backupReady: 'بکاپ آماده است — حالا می‌توانی dump را دانلود کنی',
backupFailed: 'بکاپ ناموفق بود',
backupStarted: 'بکاپ آغاز شد — dump در حال انجام',
createFailed: 'ساخت بکاپ ناموفق بود',
backupDeleted: 'بکاپ حذف شد',
deleteFailed: 'حذف بکاپ ناموفق بود',
downloadStarted: 'دانلود آغاز شد',
downloadFailed: 'دانلود dump دیتابیس ناموفق بود',
deleteConfirmTitle: 'حذف بکاپ؟',
deleteConfirmMessage: 'حذف «{label}»؟ فایل dump برای همیشه حذف می‌شود.',
snapStatus: { completed: 'کامل', failed: 'ناموفق' },
},
},
nav: {
@@ -801,6 +864,46 @@ const fa = {
hours: 'ساعت',
days: 'روز',
},
servicesNew: {
steps: ['نوع سرویس', 'پیکربندی', 'بررسی و پرداخت'],
title: 'سرویس مدیریت‌شدهٔ جدید',
subtitle: 'دیتابیس، Redis یا RabbitMQ — مثل اپلیکیشن‌ها صورت‌حساب می‌شود',
typeDatabase: 'دیتابیس',
typeDatabaseDesc: 'PostgreSQL، MySQL، MariaDB، MongoDB',
typeRedis: 'Redis',
typeRedisDesc: 'کش و ذخیرهٔ درون‌حافظه‌ای',
typeRabbitmq: 'RabbitMQ',
typeRabbitmqDesc: 'بروکر پیام',
serviceName: 'نام سرویس',
serviceNamePlaceholder: 'my-database',
nameHint: 'فقط حروف کوچک، اعداد و خط تیره',
redisVersion: 'نسخهٔ Redis',
rabbitmqVersion: 'نسخهٔ RabbitMQ',
redisResources: 'منابع Redis',
rabbitmqResources: 'منابع RabbitMQ',
billingCycle: 'دورهٔ صورت‌حساب',
cycles: { hourly: 'ساعتی', monthly: 'ماهانه', yearly: 'سالانه' },
paymentMethod: 'روش پرداخت',
wallet: 'کیف‌پول',
insufficient: 'ناکافی',
payNow: 'پرداخت',
pricingUnavailable: 'قیمت در دسترس نیست',
back: 'بازگشت',
next: 'بعدی',
payProvision: 'پرداخت و راه‌اندازی',
provisioning: 'در حال راه‌اندازی سرویس',
creatingService: 'ساخت سرویس',
uploadingDump: 'آپلود dump دیتابیس',
payment: 'پرداخت',
deploying: 'انتشار',
provisionedSuccess: 'سرویس با موفقیت راه‌اندازی شد',
deployFailed: 'انتشار ناموفق بود',
paySucceededDeployFailed: 'پرداخت موفق بود اما انتشار ناموفق شد',
payProvisionFailed: 'پرداخت یا راه‌اندازی ناموفق بود',
payFailed: 'پرداخت ناموفق بود',
insufficientBalance: 'موجودی کیف‌پول کافی نیست',
serviceDesc: 'سرویس: {name} ({cycle})',
},
},
};