i18n: локализация multi-mailbox UI и полей UserMailbox (uk/en)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-22 18:09:56 +03:00
parent 9c8d0d109a
commit ad8730c752
7 changed files with 233 additions and 20 deletions
+4 -4
View File
@@ -168,8 +168,8 @@ class MailViewTests(TestCase):
def test_connect_screen_when_not_linked(self):
response = self.client.get('/email/', HTTP_HX_REQUEST='true')
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Підключення скриньки')
self.assertContains(response, 'автоматично')
self.assertContains(response, 'Подключение ящика')
self.assertContains(response, 'автоматически')
self.assertContains(response, 'worker@aks-apteka.com.ua')
self.assertNotContains(response, 'автоматично після входу')
@@ -690,5 +690,5 @@ class MultiMailboxTests(TestCase):
mock_client.list_messages.return_value = ([], False)
connect_mailbox(self.user, email='one@aks-apteka.com.ua')
resp = self.client.get('/email/?add=1', HTTP_HX_REQUEST='true')
self.assertContains(resp, 'Підключити ще одну скриньку')
self.assertContains(resp, 'Скасувати')
self.assertContains(resp, 'Подключить ещё один ящик')
self.assertContains(resp, 'Отмена')
Binary file not shown.
+106
View File
@@ -1467,6 +1467,112 @@ msgstr "Carbonio sync record"
msgid "Журнал синхронизации Carbonio"
msgstr "Carbonio sync log"
#: apps/mail_connector/models.py:49
msgid "Адрес ящика"
msgstr "Mailbox address"
#: apps/mail_connector/models.py:50
#: templates/partials/email-connect-panel.html
msgid "Пароль ящика"
msgstr "Mailbox password"
#: apps/mail_connector/models.py:51
msgid "IMAP-хост"
msgstr "IMAP host"
#: apps/mail_connector/models.py:52
msgid "IMAP-порт"
msgstr "IMAP port"
#: apps/mail_connector/models.py:53
msgid "SMTP-хост"
msgstr "SMTP host"
#: apps/mail_connector/models.py:54
msgid "SMTP-порт"
msgstr "SMTP port"
#: apps/mail_connector/models.py:55
msgid "SSL/TLS"
msgstr "SSL/TLS"
#: apps/mail_connector/models.py:56
msgid "Проверять SSL-сертификат"
msgstr "Verify SSL certificate"
#: apps/mail_connector/models.py:57
msgid "Подключено"
msgstr "Connected"
#: apps/mail_connector/models.py:59
msgid "Активный ящик"
msgstr "Active mailbox"
#: apps/mail_connector/models.py:61
msgid "Текущий ящик в веб-почте портала. Не больше одного на сотрудника."
msgstr "Current mailbox in portal webmail. At most one active per employee."
#: apps/mail_connector/models.py:63
msgid "Последний успешный вход"
msgstr "Last successful login"
#: apps/mail_connector/models.py:66
msgid "Почтовый ящик сотрудника"
msgstr "Employee mailbox"
#: apps/mail_connector/models.py:67
msgid "Почтовые ящики сотрудников"
msgstr "Employee mailboxes"
#: templates/pages/email.html
#: templates/partials/email-connect-panel.html
msgid "Подключить ещё один ящик"
msgstr "Connect another mailbox"
#: templates/partials/email-connect-panel.html
msgid "Добавьте другой почтовый адрес. Текущий ящик не изменится — потом можно переключаться между ними."
msgstr "Add another email address. The current mailbox stays connected — you can switch later."
#: templates/partials/email-connect-panel.html
msgid "Подключение ящика"
msgstr "Connect mailbox"
#: templates/partials/email-connect-panel.html
msgid "Подключите свою почту: укажите адрес и пароль. Параметры сервера определяются автоматически (как в Thunderbird);"
msgstr "Connect your mail: enter address and password. Server settings are detected automatically (like Thunderbird);"
#: templates/partials/email-connect-panel.html
msgid "если автоконфиг не найден — попробуем <strong>%(host)s</strong>."
msgstr "if autoconfig is not found — we will try <strong>%(host)s</strong>."
#: templates/partials/email-connect-panel.html
msgid "Подключить"
msgstr "Connect"
#: templates/partials/email-connect-panel.html
msgid "Подключено. Перенаправление…"
msgstr "Connected. Redirecting…"
#: templates/pages/email.html
msgid "Почтовый ящик"
msgstr "Mailbox"
#: templates/pages/email.html
msgid "Тема, email, домен…"
msgstr "Subject, email, domain…"
#: templates/pages/email.html
msgid "Выйти из ящика"
msgstr "Disconnect mailbox"
#: templates/pages/email.html
msgid "Написать"
msgstr "Compose"
#: templates/pages/email.html
msgid "Выйти"
msgstr "Sign out"
#: apps/nextcloud_connector/models.py:20
msgid "Создание папки"
msgstr "Folder creation"
Binary file not shown.
+106
View File
@@ -1470,6 +1470,112 @@ msgstr "Запис синхронізації Carbonio"
msgid "Журнал синхронизации Carbonio"
msgstr "Журнал синхронізації Carbonio"
#: apps/mail_connector/models.py:49
msgid "Адрес ящика"
msgstr "Адреса скриньки"
#: apps/mail_connector/models.py:50
#: templates/partials/email-connect-panel.html
msgid "Пароль ящика"
msgstr "Пароль скриньки"
#: apps/mail_connector/models.py:51
msgid "IMAP-хост"
msgstr "IMAP-хост"
#: apps/mail_connector/models.py:52
msgid "IMAP-порт"
msgstr "IMAP-порт"
#: apps/mail_connector/models.py:53
msgid "SMTP-хост"
msgstr "SMTP-хост"
#: apps/mail_connector/models.py:54
msgid "SMTP-порт"
msgstr "SMTP-порт"
#: apps/mail_connector/models.py:55
msgid "SSL/TLS"
msgstr "SSL/TLS"
#: apps/mail_connector/models.py:56
msgid "Проверять SSL-сертификат"
msgstr "Перевіряти SSL-сертифікат"
#: apps/mail_connector/models.py:57
msgid "Подключено"
msgstr "Підключено"
#: apps/mail_connector/models.py:59
msgid "Активный ящик"
msgstr "Активна скринька"
#: apps/mail_connector/models.py:61
msgid "Текущий ящик в веб-почте портала. Не больше одного на сотрудника."
msgstr "Поточна скринька у веб-пошті порталу. Не більше однієї на співробітника."
#: apps/mail_connector/models.py:63
msgid "Последний успешный вход"
msgstr "Останній успішний вхід"
#: apps/mail_connector/models.py:66
msgid "Почтовый ящик сотрудника"
msgstr "Поштова скринька співробітника"
#: apps/mail_connector/models.py:67
msgid "Почтовые ящики сотрудников"
msgstr "Поштові скриньки співробітників"
#: templates/pages/email.html
#: templates/partials/email-connect-panel.html
msgid "Подключить ещё один ящик"
msgstr "Підключити ще одну скриньку"
#: templates/partials/email-connect-panel.html
msgid "Добавьте другой почтовый адрес. Текущий ящик не изменится — потом можно переключаться между ними."
msgstr "Додайте іншу поштову адресу. Поточну скриньку це не змінить — потім можна перемикатися між ними."
#: templates/partials/email-connect-panel.html
msgid "Подключение ящика"
msgstr "Підключення скриньки"
#: templates/partials/email-connect-panel.html
msgid "Подключите свою почту: укажите адрес и пароль. Параметры сервера определяются автоматически (как в Thunderbird);"
msgstr "Підключіть свою пошту: вкажіть адресу та пароль. Параметри сервера визначаються автоматично (як у Thunderbird);"
#: templates/partials/email-connect-panel.html
msgid "если автоконфиг не найден — попробуем <strong>%(host)s</strong>."
msgstr "якщо автоконфіг не знайдено — спробуємо <strong>%(host)s</strong>."
#: templates/partials/email-connect-panel.html
msgid "Подключить"
msgstr "Підключити"
#: templates/partials/email-connect-panel.html
msgid "Подключено. Перенаправление…"
msgstr "Підключено. Перенаправлення…"
#: templates/pages/email.html
msgid "Почтовый ящик"
msgstr "Поштова скринька"
#: templates/pages/email.html
msgid "Тема, email, домен…"
msgstr "Тема, email, домен…"
#: templates/pages/email.html
msgid "Выйти из ящика"
msgstr "Вийти зі скриньки"
#: templates/pages/email.html
msgid "Написать"
msgstr "Написати"
#: templates/pages/email.html
msgid "Выйти"
msgstr "Вийти"
#: apps/nextcloud_connector/models.py:20
msgid "Создание папки"
msgstr "Створення папки"
+7 -6
View File
@@ -1,4 +1,5 @@
{# Rainloop-style webmail layout #}
{% load i18n %}
{% if not mail_configured %}
<div class="page-content">
<div class="mail-notice">{{ mail_error }}</div>
@@ -21,7 +22,7 @@
hx-trigger="change">
{% csrf_token %}
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-10 7L2 7"/></svg>
<select name="mailbox_id" class="mail-toolbar-select" title="Поштова скринька" aria-label="Поштова скринька">
<select name="mailbox_id" class="mail-toolbar-select" title="{% trans "Почтовый ящик" %}" aria-label="{% trans "Почтовый ящик" %}">
{% for box in mailboxes %}
<option value="{{ box.uuid }}"{% if box.is_active %} selected{% endif %}>{{ box.email }}</option>
{% endfor %}
@@ -36,13 +37,13 @@
<a href="/email/?add=1"
hx-get="/email/?add=1"
hx-target="#main-content" hx-push-url="/email/?add=1" hx-indicator="#loader"
class="mail-btn mail-btn-ghost" title="Підключити ще одну скриньку">Додати</a>
class="mail-btn mail-btn-ghost" title="{% trans "Подключить ещё один ящик" %}">{% trans "Добавить" %}</a>
<a href="/email/?view=compose&folder={{ active_folder }}"
hx-get="/email/?view=compose&folder={{ active_folder }}"
hx-target="#main-content" hx-push-url="/email/?view=compose&folder={{ active_folder }}" hx-indicator="#loader"
class="mail-btn mail-btn-compose">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
Написати
{% trans "Написать" %}
</a>
</div>
<form class="mail-toolbar-search" method="get" action="/email/"
@@ -54,7 +55,7 @@
<input type="hidden" name="folder" value="{{ active_folder }}">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
<input type="search" name="q" value="{{ search_q|default:'' }}"
placeholder="Тема, email, домен…"
placeholder="{% trans "Тема, email, домен…" %}"
autocomplete="off"
enterkeyhint="search">
</form>
@@ -62,12 +63,12 @@
<a href="/email/?folder={{ active_folder }}{% if search_q %}&q={{ search_q|urlencode }}{% endif %}"
hx-get="/email/?folder={{ active_folder }}{% if search_q %}&q={{ search_q|urlencode }}{% endif %}"
hx-target="#main-content" hx-push-url="true" hx-indicator="#loader"
class="mail-btn mail-btn-ghost" title="Оновити">
class="mail-btn mail-btn-ghost" title="{% trans "Обновить" %}">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 1 1-9-9c2.5 0 4.8 1 6.5 2.7L21 8"/><path d="M21 3v5h-5"/></svg>
</a>
<form hx-post="/email/disconnect/" hx-target="#main-content" hx-indicator="#loader" style="margin:0;">
{% csrf_token %}
<button type="submit" class="mail-btn mail-btn-ghost" title="Вийти зі скриньки">Вийти</button>
<button type="submit" class="mail-btn mail-btn-ghost" title="{% trans "Выйти из ящика" %}">{% trans "Выйти" %}</button>
</form>
</div>
</header>
+10 -10
View File
@@ -1,15 +1,15 @@
{% load i18n %}
<div id="email-connect-panel" style="max-width:32rem; background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); padding:1.5rem; box-shadow:0 1px 2px rgb(0 0 0/0.05);">
{% if adding_mailbox %}
<h2 style="font-size:1rem; font-weight:500; margin-bottom:0.5rem;">Підключити ще одну скриньку</h2>
<h2 style="font-size:1rem; font-weight:500; margin-bottom:0.5rem;">{% trans "Подключить ещё один ящик" %}</h2>
<p style="font-size:0.8125rem; color:var(--color-muted-foreground); margin-bottom:1rem;">
Додайте іншу поштову адресу. Поточну скриньку це не змінить — потім можна перемикатися між ними.
{% trans "Добавьте другой почтовый адрес. Текущий ящик не изменится — потом можно переключаться между ними." %}
</p>
{% else %}
<h2 style="font-size:1rem; font-weight:500; margin-bottom:0.5rem;">Підключення скриньки</h2>
<h2 style="font-size:1rem; font-weight:500; margin-bottom:0.5rem;">{% trans "Подключение ящика" %}</h2>
<p style="font-size:0.8125rem; color:var(--color-muted-foreground); margin-bottom:1rem;">
Підключіть свою пошту: вкажіть адресу та пароль.
Параметри сервера визначаються автоматично (як у Thunderbird);
{% if mail_defaults %}якщо автоконфіг не знайдено — спробуємо <strong>{{ mail_defaults.imap_host }}</strong>.{% endif %}
{% trans "Подключите свою почту: укажите адрес и пароль. Параметры сервера определяются автоматически (как в Thunderbird);" %}
{% if mail_defaults %}{% blocktrans with host=mail_defaults.imap_host %}если автоконфиг не найден — попробуем <strong>{{ host }}</strong>.{% endblocktrans %}{% endif %}
</p>
{% endif %}
{% if connect_error %}
@@ -32,22 +32,22 @@
hx-target="#email-autoconfig-fields"
hx-indicator="#loader"
hx-include="closest form">
<label style="display:block; font-size:0.8125rem; font-weight:500; margin-bottom:0.375rem;">Пароль скриньки</label>
<label style="display:block; font-size:0.8125rem; font-weight:500; margin-bottom:0.375rem;">{% trans "Пароль ящика" %}</label>
<input type="password" name="password" required autocomplete="current-password" class="input" style="width:100%; margin-bottom:0.875rem;">
<div id="email-autoconfig-fields">
{% include "partials/email-autoconfig-fields.html" %}
</div>
<div style="display:flex; gap:0.5rem; align-items:center; flex-wrap:wrap;">
<button type="submit" class="btn btn-primary">Підключити</button>
<button type="submit" class="btn btn-primary">{% trans "Подключить" %}</button>
{% if adding_mailbox %}
<a href="/email/"
hx-get="/email/"
hx-target="#main-content" hx-push-url="/email/" hx-indicator="#loader"
class="btn" style="text-decoration:none;">Скасувати</a>
class="btn" style="text-decoration:none;">{% trans "Отмена" %}</a>
{% endif %}
</div>
</form>
{% if connect_success %}
<div style="margin-top:0.75rem; font-size:0.8125rem; color:hsl(152 55% 35%);">Підключено. Перенаправлення…</div>
<div style="margin-top:0.75rem; font-size:0.8125rem; color:hsl(152 55% 35%);">{% trans "Подключено. Перенаправление…" %}</div>
{% endif %}
</div>