i18n: перевод модуля задач (tasks/task-detail/task-edit) ru/uk/en

- Task.STATUS_CHOICES/PRIORITY_CHOICES переведены на русские msgid
  (консистентно с ru-базой); миграция choices
- task_detail_view: метки ролей через gettext
- Шаблоны tasks/task-detail/task-edit размечены {% trans %}; статусы,
  приоритеты, чек-лист, комментарии, участники, кнопки действий — uk/en

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 14:55:48 +03:00
parent 443135fe33
commit 87cb9de005
10 changed files with 415 additions and 130 deletions
@@ -0,0 +1,23 @@
# Generated by Django 6.0.3 on 2026-07-25 11:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tasks', '0004_taskchecklistitem'),
]
operations = [
migrations.AlterField(
model_name='task',
name='priority',
field=models.CharField(choices=[('low', 'Низкий'), ('medium', 'Средний'), ('high', 'Высокий')], db_index=True, default='medium', max_length=10, verbose_name='Пріоритет'),
),
migrations.AlterField(
model_name='task',
name='status',
field=models.CharField(choices=[('pending', 'Ожидает'), ('in_progress', 'В работе'), ('done', 'Выполнено'), ('cancelled', 'Отменено')], db_index=True, default='pending', max_length=20, verbose_name='Статус'),
),
]
+7 -7
View File
@@ -21,16 +21,16 @@ class TaskQuerySet(models.QuerySet):
class Task(BaseModel):
STATUS_CHOICES = [
('pending', _('Очікує')),
('in_progress', _('В роботі')),
('done', _('Виконано')),
('cancelled', _('Скасовано')),
('pending', _('Ожидает')),
('in_progress', _('В работе')),
('done', _('Выполнено')),
('cancelled', _('Отменено')),
]
PRIORITY_CHOICES = [
('low', _('Низький')),
('medium', _('Середній')),
('high', _('Високий')),
('low', _('Низкий')),
('medium', _('Средний')),
('high', _('Высокий')),
]
PRIORITY_BADGES = {'low': 'badge-muted', 'medium': 'badge-warning', 'high': 'badge-danger'}
+4 -3
View File
@@ -4,6 +4,7 @@ from django.db.models import Count, Prefetch, Q
from django.http import Http404
from django.shortcuts import get_object_or_404, redirect
from django.views.decorators.http import require_POST
from django.utils.translation import gettext_lazy as _
from apps.tasks.models import Task, TaskComment
from core.models.directories import Directory
@@ -207,9 +208,9 @@ def task_detail_view(request, pk):
'can_edit': can_edit_task(request.user, task),
'can_delete': can_delete_task(request.user, task),
'role_groups': [
('Відповідальний', list(task.responsible.all())),
('Співвиконавці', list(task.co_executors.all())),
('Спостерігачі', list(task.observers.all())),
(_('Ответственный'), list(task.responsible.all())),
(_('Соисполнители'), list(task.co_executors.all())),
(_('Наблюдатели'), list(task.observers.all())),
],
}
return render_page(request, 'task-detail.html', context)
Binary file not shown.
+161 -33
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-25 12:03+0300\n"
"POT-Creation-Date: 2026-07-25 14:54+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -323,7 +323,9 @@ msgstr ""
msgid "Статус синхронизации Mattermost"
msgstr ""
#: apps/employees/models/base.py:142 templates/pages/employee-detail.html:148
#: apps/employees/models/base.py:142 apps/tasks/models.py:24
#: templates/pages/employee-detail.html:148 templates/pages/task-detail.html:25
#: templates/pages/tasks.html:64 templates/pages/tasks.html:116
msgid "Ожидает"
msgstr "Pending"
@@ -396,8 +398,9 @@ msgstr ""
#: apps/employees/models/permissions.py:16 apps/it_manager/admin.py:611
#: core/models/directories.py:28 core/models/directories.py:120
#: templates/pages/task-detail.html:62
msgid "Описание"
msgstr ""
msgstr "Description"
#: apps/employees/models/permissions.py:17 apps/locations/models/base.py:59
msgid "Активна"
@@ -515,8 +518,9 @@ msgid ""
msgstr ""
#: apps/feed/models.py:61 apps/feed/models.py:100 apps/tasks/models.py:126
#: templates/pages/task-detail.html:200
msgid "Автор"
msgstr ""
msgstr "Author"
#: apps/feed/models.py:65 apps/feed/models.py:96
msgid "Пост"
@@ -707,9 +711,9 @@ msgstr ""
msgid "Заявка"
msgstr ""
#: apps/it_manager/admin.py:298
#: apps/it_manager/admin.py:298 templates/pages/task-detail.html:171
msgid "Участники"
msgstr ""
msgstr "Participants"
#: apps/it_manager/admin.py:301 apps/it_manager/admin.py:614
#: apps/it_manager/admin.py:670
@@ -728,9 +732,9 @@ msgstr ""
msgid "SLA"
msgstr ""
#: apps/it_manager/admin.py:366
#: apps/it_manager/admin.py:366 templates/pages/task-detail.html:143
msgid "Взять в работу"
msgstr ""
msgstr "Take in progress"
#: apps/it_manager/admin.py:375
msgid "Отметить решёнными"
@@ -925,9 +929,9 @@ msgstr ""
msgid "Заполняется автоматически из полей выше"
msgstr ""
#: apps/locations/models/base.py:60
#: apps/locations/models/base.py:60 templates/pages/task-detail.html:98
msgid "Комментарии"
msgstr ""
msgstr "Comments"
#: apps/locations/models/base.py:66
msgid "Локации"
@@ -1140,33 +1144,33 @@ msgstr ""
msgid "Журнал синхронизации Carbonio"
msgstr ""
#: apps/tasks/models.py:24
msgid "Очікує"
msgstr ""
#: apps/tasks/models.py:25 templates/pages/task-detail.html:21
#: templates/pages/tasks.html:68 templates/pages/tasks.html:108
msgid "В работе"
msgstr "In progress"
#: apps/tasks/models.py:25
msgid "В роботі"
msgstr ""
#: apps/tasks/models.py:26 templates/pages/task-detail.html:19
#: templates/pages/task-detail.html:209 templates/pages/tasks.html:72
#: templates/pages/tasks.html:104
msgid "Выполнено"
msgstr "Done"
#: apps/tasks/models.py:26 apps/tasks/models.py:147
msgid "Виконано"
msgstr ""
#: apps/tasks/models.py:27
msgid "Скасовано"
msgstr ""
#: apps/tasks/models.py:27 templates/pages/task-detail.html:23
#: templates/pages/tasks.html:112
msgid "Отменено"
msgstr "Cancelled"
#: apps/tasks/models.py:31
msgid "Низький"
msgstr ""
msgid "Низкий"
msgstr "Low"
#: apps/tasks/models.py:32
msgid "Середній"
msgstr ""
msgid "Средний"
msgstr "Medium"
#: apps/tasks/models.py:33
msgid "Високий"
msgstr ""
msgid "Высокий"
msgstr "High"
#: apps/tasks/models.py:38
msgid "Назва"
@@ -1224,6 +1228,10 @@ msgstr ""
msgid "Пункт"
msgstr ""
#: apps/tasks/models.py:147
msgid "Виконано"
msgstr ""
#: apps/tasks/models.py:151
msgid "Відмітив"
msgstr ""
@@ -1240,6 +1248,21 @@ msgstr ""
msgid "Чек-лист задачі"
msgstr ""
#: apps/tasks/views.py:211 templates/pages/task-edit.html:2
#: templates/pages/tasks.html:35
msgid "Ответственный"
msgstr "Responsible"
#: apps/tasks/views.py:212 templates/pages/task-edit.html:2
#: templates/pages/tasks.html:35
msgid "Соисполнители"
msgstr "Co-executors"
#: apps/tasks/views.py:213 templates/pages/task-edit.html:2
#: templates/pages/tasks.html:35
msgid "Наблюдатели"
msgstr "Observers"
#: apps/utilities/models.py:22
msgid "Тип лічильника"
msgstr ""
@@ -1618,7 +1641,7 @@ msgid "Новости"
msgstr "News"
#: templates/index.html:260 templates/index.html:660
#: templates/pages/dashboard.html:145
#: templates/pages/dashboard.html:145 templates/pages/task-detail.html:10
msgid "Задачи"
msgstr "Tasks"
@@ -1750,7 +1773,7 @@ msgstr "Today"
msgid "г."
msgstr "y."
#: templates/pages/dashboard.html:10
#: templates/pages/dashboard.html:10 templates/pages/tasks.html:7
msgid "Мои задачи"
msgstr "My tasks"
@@ -1822,7 +1845,8 @@ msgstr "Useful links and tools"
msgid "Справочник"
msgstr "Directory"
#: templates/pages/employee-detail.html:21
#: templates/pages/employee-detail.html:21 templates/pages/task-detail.html:41
#: templates/pages/tasks.html:127
msgid "Редактировать"
msgstr "Edit"
@@ -1900,7 +1924,7 @@ msgstr "Add employee"
msgid "сотрудников, из них"
msgstr "employees, of them"
#: templates/pages/employees.html:48
#: templates/pages/employees.html:48 templates/pages/tasks.html:60
msgid "Все"
msgstr "All"
@@ -1923,3 +1947,107 @@ msgstr "Start date"
#: templates/pages/employees.html:157
msgid "Список сотрудников пуст."
msgstr "Employee list is empty."
#: templates/pages/task-detail.html:30
msgid "срок:"
msgstr "due:"
#: templates/pages/task-detail.html:30
msgid "просрочено"
msgstr "overdue"
#: templates/pages/task-detail.html:46 templates/pages/tasks.html:133
msgid "Удалить задачу"
msgstr "Delete task"
#: templates/pages/task-detail.html:48 templates/pages/tasks.html:135
msgid "Удалить"
msgstr "Delete"
#: templates/pages/task-detail.html:66
msgid "Описание не добавлено"
msgstr "No description"
#: templates/pages/task-detail.html:74
msgid "Чек-лист"
msgstr "Checklist"
#: templates/pages/task-detail.html:116
msgid "Комментариев пока нет"
msgstr "No comments yet"
#: templates/pages/task-detail.html:125
msgid "Написать комментарий..."
msgstr "Write a comment..."
#: templates/pages/task-detail.html:127
msgid "Отправить"
msgstr "Send"
#: templates/pages/task-detail.html:138
msgid "Действия"
msgstr "Actions"
#: templates/pages/task-detail.html:156
msgid "Вернуть в работу"
msgstr "Return to progress"
#: templates/pages/task-detail.html:163
msgid "Отменить задачу"
msgstr "Cancel task"
#: templates/pages/task-detail.html:192
msgid "Не назначено"
msgstr "Not assigned"
#: templates/pages/task-detail.html:204
msgid "Создано"
msgstr "Created"
#: templates/pages/task-edit.html:2 templates/pages/tasks.html:35
msgid "+ Добавить ответственного"
msgstr "+ Add responsible"
#: templates/pages/task-edit.html:2 templates/pages/tasks.html:35
msgid "+ Добавить соисполнителя"
msgstr "+ Add co-executor"
#: templates/pages/task-edit.html:2 templates/pages/tasks.html:35
msgid "+ Добавить наблюдателя"
msgstr "+ Add observer"
#: templates/pages/task-edit.html:15
msgid "Редактирование задачи"
msgstr "Edit task"
#: templates/pages/task-edit.html:29 templates/pages/tasks.html:31
msgid "Название задачи"
msgstr "Task title"
#: templates/pages/task-edit.html:30 templates/pages/tasks.html:32
msgid "Описание задачи (необязательно)..."
msgstr "Task description (optional)..."
#: templates/pages/task-edit.html:46
msgid "Сохранить изменения"
msgstr "Save changes"
#: templates/pages/tasks.html:8
msgid "Задачи, созданные вами или назначенные вам"
msgstr "Tasks created by or assigned to you"
#: templates/pages/tasks.html:26
msgid "Новая задача"
msgstr "New task"
#: templates/pages/tasks.html:49
msgid "Создать задачу"
msgstr "Create task"
#: templates/pages/tasks.html:144
msgid "Задач с таким статусом нет"
msgstr "No tasks with this status"
#: templates/pages/tasks.html:144
msgid "Задач пока нет — создайте первую"
msgstr "No tasks yet — create the first"
Binary file not shown.
+161 -33
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-25 12:03+0300\n"
"POT-Creation-Date: 2026-07-25 14:54+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -326,7 +326,9 @@ msgstr ""
msgid "Статус синхронизации Mattermost"
msgstr ""
#: apps/employees/models/base.py:142 templates/pages/employee-detail.html:148
#: apps/employees/models/base.py:142 apps/tasks/models.py:24
#: templates/pages/employee-detail.html:148 templates/pages/task-detail.html:25
#: templates/pages/tasks.html:64 templates/pages/tasks.html:116
msgid "Ожидает"
msgstr "Очікує"
@@ -399,8 +401,9 @@ msgstr ""
#: apps/employees/models/permissions.py:16 apps/it_manager/admin.py:611
#: core/models/directories.py:28 core/models/directories.py:120
#: templates/pages/task-detail.html:62
msgid "Описание"
msgstr ""
msgstr "Опис"
#: apps/employees/models/permissions.py:17 apps/locations/models/base.py:59
msgid "Активна"
@@ -518,8 +521,9 @@ msgid ""
msgstr ""
#: apps/feed/models.py:61 apps/feed/models.py:100 apps/tasks/models.py:126
#: templates/pages/task-detail.html:200
msgid "Автор"
msgstr ""
msgstr "Автор"
#: apps/feed/models.py:65 apps/feed/models.py:96
msgid "Пост"
@@ -710,9 +714,9 @@ msgstr ""
msgid "Заявка"
msgstr ""
#: apps/it_manager/admin.py:298
#: apps/it_manager/admin.py:298 templates/pages/task-detail.html:171
msgid "Участники"
msgstr ""
msgstr "Учасники"
#: apps/it_manager/admin.py:301 apps/it_manager/admin.py:614
#: apps/it_manager/admin.py:670
@@ -731,9 +735,9 @@ msgstr ""
msgid "SLA"
msgstr ""
#: apps/it_manager/admin.py:366
#: apps/it_manager/admin.py:366 templates/pages/task-detail.html:143
msgid "Взять в работу"
msgstr ""
msgstr "Взяти в роботу"
#: apps/it_manager/admin.py:375
msgid "Отметить решёнными"
@@ -928,9 +932,9 @@ msgstr ""
msgid "Заполняется автоматически из полей выше"
msgstr ""
#: apps/locations/models/base.py:60
#: apps/locations/models/base.py:60 templates/pages/task-detail.html:98
msgid "Комментарии"
msgstr ""
msgstr "Коментарі"
#: apps/locations/models/base.py:66
msgid "Локации"
@@ -1143,33 +1147,33 @@ msgstr ""
msgid "Журнал синхронизации Carbonio"
msgstr ""
#: apps/tasks/models.py:24
msgid "Очікує"
msgstr ""
#: apps/tasks/models.py:25 templates/pages/task-detail.html:21
#: templates/pages/tasks.html:68 templates/pages/tasks.html:108
msgid "В работе"
msgstr "В роботі"
#: apps/tasks/models.py:25
msgid "В роботі"
msgstr ""
#: apps/tasks/models.py:26 templates/pages/task-detail.html:19
#: templates/pages/task-detail.html:209 templates/pages/tasks.html:72
#: templates/pages/tasks.html:104
msgid "Выполнено"
msgstr "Виконано"
#: apps/tasks/models.py:26 apps/tasks/models.py:147
msgid "Виконано"
msgstr ""
#: apps/tasks/models.py:27
msgid "Скасовано"
msgstr ""
#: apps/tasks/models.py:27 templates/pages/task-detail.html:23
#: templates/pages/tasks.html:112
msgid "Отменено"
msgstr "Скасовано"
#: apps/tasks/models.py:31
msgid "Низький"
msgstr ""
msgid "Низкий"
msgstr "Низький"
#: apps/tasks/models.py:32
msgid "Середній"
msgstr ""
msgid "Средний"
msgstr "Середній"
#: apps/tasks/models.py:33
msgid "Високий"
msgstr ""
msgid "Высокий"
msgstr "Високий"
#: apps/tasks/models.py:38
msgid "Назва"
@@ -1227,6 +1231,10 @@ msgstr ""
msgid "Пункт"
msgstr ""
#: apps/tasks/models.py:147
msgid "Виконано"
msgstr ""
#: apps/tasks/models.py:151
msgid "Відмітив"
msgstr ""
@@ -1243,6 +1251,21 @@ msgstr ""
msgid "Чек-лист задачі"
msgstr ""
#: apps/tasks/views.py:211 templates/pages/task-edit.html:2
#: templates/pages/tasks.html:35
msgid "Ответственный"
msgstr "Відповідальний"
#: apps/tasks/views.py:212 templates/pages/task-edit.html:2
#: templates/pages/tasks.html:35
msgid "Соисполнители"
msgstr "Співвиконавці"
#: apps/tasks/views.py:213 templates/pages/task-edit.html:2
#: templates/pages/tasks.html:35
msgid "Наблюдатели"
msgstr "Спостерігачі"
#: apps/utilities/models.py:22
msgid "Тип лічильника"
msgstr ""
@@ -1621,7 +1644,7 @@ msgid "Новости"
msgstr "Новини"
#: templates/index.html:260 templates/index.html:660
#: templates/pages/dashboard.html:145
#: templates/pages/dashboard.html:145 templates/pages/task-detail.html:10
msgid "Задачи"
msgstr "Задачі"
@@ -1753,7 +1776,7 @@ msgstr "Сьогодні"
msgid "г."
msgstr "р."
#: templates/pages/dashboard.html:10
#: templates/pages/dashboard.html:10 templates/pages/tasks.html:7
msgid "Мои задачи"
msgstr "Мої задачі"
@@ -1825,7 +1848,8 @@ msgstr "Корисні посилання та інструменти"
msgid "Справочник"
msgstr "Довідник"
#: templates/pages/employee-detail.html:21
#: templates/pages/employee-detail.html:21 templates/pages/task-detail.html:41
#: templates/pages/tasks.html:127
msgid "Редактировать"
msgstr "Редагувати"
@@ -1903,7 +1927,7 @@ msgstr "Додати співробітника"
msgid "сотрудников, из них"
msgstr "співробітників, з них"
#: templates/pages/employees.html:48
#: templates/pages/employees.html:48 templates/pages/tasks.html:60
msgid "Все"
msgstr "Всі"
@@ -1926,3 +1950,107 @@ msgstr "Дата початку"
#: templates/pages/employees.html:157
msgid "Список сотрудников пуст."
msgstr "Список співробітників порожній."
#: templates/pages/task-detail.html:30
msgid "срок:"
msgstr "термін:"
#: templates/pages/task-detail.html:30
msgid "просрочено"
msgstr "прострочено"
#: templates/pages/task-detail.html:46 templates/pages/tasks.html:133
msgid "Удалить задачу"
msgstr "Видалити задачу"
#: templates/pages/task-detail.html:48 templates/pages/tasks.html:135
msgid "Удалить"
msgstr "Видалити"
#: templates/pages/task-detail.html:66
msgid "Описание не добавлено"
msgstr "Опис не додано"
#: templates/pages/task-detail.html:74
msgid "Чек-лист"
msgstr "Чек-лист"
#: templates/pages/task-detail.html:116
msgid "Комментариев пока нет"
msgstr "Коментарів поки немає"
#: templates/pages/task-detail.html:125
msgid "Написать комментарий..."
msgstr "Написати коментар..."
#: templates/pages/task-detail.html:127
msgid "Отправить"
msgstr "Надіслати"
#: templates/pages/task-detail.html:138
msgid "Действия"
msgstr "Дії"
#: templates/pages/task-detail.html:156
msgid "Вернуть в работу"
msgstr "Повернути в роботу"
#: templates/pages/task-detail.html:163
msgid "Отменить задачу"
msgstr "Скасувати задачу"
#: templates/pages/task-detail.html:192
msgid "Не назначено"
msgstr "Не призначено"
#: templates/pages/task-detail.html:204
msgid "Создано"
msgstr "Створено"
#: templates/pages/task-edit.html:2 templates/pages/tasks.html:35
msgid "+ Добавить ответственного"
msgstr "+ Додати відповідального"
#: templates/pages/task-edit.html:2 templates/pages/tasks.html:35
msgid "+ Добавить соисполнителя"
msgstr "+ Додати співвиконавця"
#: templates/pages/task-edit.html:2 templates/pages/tasks.html:35
msgid "+ Добавить наблюдателя"
msgstr "+ Додати спостерігача"
#: templates/pages/task-edit.html:15
msgid "Редактирование задачи"
msgstr "Редагування задачі"
#: templates/pages/task-edit.html:29 templates/pages/tasks.html:31
msgid "Название задачи"
msgstr "Назва задачі"
#: templates/pages/task-edit.html:30 templates/pages/tasks.html:32
msgid "Описание задачи (необязательно)..."
msgstr "Опис задачі (необов'язково)..."
#: templates/pages/task-edit.html:46
msgid "Сохранить изменения"
msgstr "Зберегти зміни"
#: templates/pages/tasks.html:8
msgid "Задачи, созданные вами или назначенные вам"
msgstr "Задачі, створені вами або призначені вам"
#: templates/pages/tasks.html:26
msgid "Новая задача"
msgstr "Нова задача"
#: templates/pages/tasks.html:49
msgid "Создать задачу"
msgstr "Створити задачу"
#: templates/pages/tasks.html:144
msgid "Задач с таким статусом нет"
msgstr "Задач з таким статусом немає"
#: templates/pages/tasks.html:144
msgid "Задач пока нет — создайте первую"
msgstr "Задач поки немає — створіть першу"
+26 -25
View File
@@ -1,4 +1,5 @@
{% load common_tags %}
{% load i18n %}
<div class="page-content">
<!-- Назад -->
@@ -6,7 +7,7 @@
<a class="btn btn-ghost" style="padding:0.375rem 0.5rem; font-size:0.8125rem; gap:0.375rem; color:var(--color-muted-foreground); cursor:pointer; text-decoration:none;"
href="/tasks/" hx-get="/tasks/" hx-target="#main-content" hx-push-url="/tasks/" hx-indicator="#loader">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 18-6-6 6-6"/></svg>
Задачі
{% trans "Задачи" %}
</a>
</div>
@@ -15,18 +16,18 @@
<div style="flex:1;">
<div style="display:flex; align-items:center; gap:0.625rem; margin-bottom:0.5rem; flex-wrap:wrap;">
{% if task.status == 'done' %}
<span class="badge badge-success" style="gap:0.25rem;">✓ Виконано</span>
<span class="badge badge-success" style="gap:0.25rem;">✓ {% trans "Выполнено" %}</span>
{% elif task.status == 'in_progress' %}
<span class="badge badge-success" style="gap:0.25rem;"><span style="width:6px; height:6px; border-radius:50%; background:hsl(152 55% 45%);"></span>В роботі</span>
<span class="badge badge-success" style="gap:0.25rem;"><span style="width:6px; height:6px; border-radius:50%; background:hsl(152 55% 45%);"></span>{% trans "В работе" %}</span>
{% elif task.status == 'cancelled' %}
<span class="badge badge-muted">Скасовано</span>
<span class="badge badge-muted">{% trans "Отменено" %}</span>
{% else %}
<span class="badge badge-warning" style="gap:0.25rem;"><span style="width:6px; height:6px; border-radius:50%; background:hsl(38 92% 50%);"></span>Очікує</span>
<span class="badge badge-warning" style="gap:0.25rem;"><span style="width:6px; height:6px; border-radius:50%; background:hsl(38 92% 50%);"></span>{% trans "Ожидает" %}</span>
{% endif %}
<span class="badge {{ task.priority_badge }}">{{ task.get_priority_display }}</span>
{% if task.due_date %}
<span style="font-size:0.75rem; color:{% if task.is_overdue %}var(--color-destructive); font-weight:600;{% else %}var(--color-muted-foreground);{% endif %}">
термін: {{ task.due_date|date:"d.m.Y" }}{% if task.is_overdue %} — прострочено{% endif %}
{% trans "срок:" %} {{ task.due_date|date:"d.m.Y" }}{% if task.is_overdue %} — {% trans "просрочено" %}{% endif %}
</span>
{% endif %}
</div>
@@ -37,14 +38,14 @@
<a href="/tasks/{{ task.pk }}/edit/" hx-get="/tasks/{{ task.pk }}/edit/" hx-target="#main-content" hx-push-url="/tasks/{{ task.pk }}/edit/" hx-indicator="#loader"
class="btn btn-secondary" style="font-size:0.8125rem; text-decoration:none;">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
Редагувати
{% trans "Редактировать" %}
</a>
{% endif %}
{% if can_delete %}
<form hx-post="/tasks/{{ task.pk }}/delete/" hx-target="#main-content" hx-push-url="/tasks/" hx-indicator="#loader"
hx-confirm="Видалити задачу «{{ task.title }}»?" style="margin:0;">
hx-confirm="{% trans 'Удалить задачу' %} «{{ task.title }}»?" style="margin:0;">
{% csrf_token %}
<button type="submit" class="btn btn-ghost" style="font-size:0.8125rem; color:var(--color-destructive);">Видалити</button>
<button type="submit" class="btn btn-ghost" style="font-size:0.8125rem; color:var(--color-destructive);">{% trans "Удалить" %}</button>
</form>
{% endif %}
</div>
@@ -58,11 +59,11 @@
<!-- Опис -->
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); padding:1.25rem;">
<h3 style="font-size:0.875rem; font-weight:600; color:var(--color-foreground); margin-bottom:0.75rem;">Опис</h3>
<h3 style="font-size:0.875rem; font-weight:600; color:var(--color-foreground); margin-bottom:0.75rem;">{% trans "Описание" %}</h3>
{% if task.description %}
<div style="font-size:0.875rem; color:var(--color-muted-foreground); line-height:1.6; white-space:pre-line;">{{ task.description }}</div>
{% else %}
<div style="font-size:0.875rem; color:var(--color-muted-foreground); opacity:0.6;">Опис не додано</div>
<div style="font-size:0.875rem; color:var(--color-muted-foreground); opacity:0.6;">{% trans "Описание не добавлено" %}</div>
{% endif %}
</div>
@@ -70,7 +71,7 @@
{% if checklist %}
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); padding:1.25rem;">
<div style="display:flex; align-items:center; gap:0.5rem; margin-bottom:0.75rem;">
<h3 style="font-size:0.875rem; font-weight:600; color:var(--color-foreground);">Чек-лист</h3>
<h3 style="font-size:0.875rem; font-weight:600; color:var(--color-foreground);">{% trans "Чек-лист" %}</h3>
<span style="font-size:0.6875rem; background:var(--color-muted); color:var(--color-muted-foreground); border-radius:999px; padding:0.0625rem 0.5rem; font-weight:500;">{{ task.checklist_done }}/{{ task.checklist_total }}</span>
</div>
<div style="display:flex; flex-direction:column; gap:0.125rem;">
@@ -94,7 +95,7 @@
<!-- Коментарі -->
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); overflow:hidden;">
<div style="padding:1rem 1.25rem; border-bottom:1px solid var(--color-border); display:flex; align-items:center; gap:0.5rem;">
<h3 style="font-size:0.875rem; font-weight:600; color:var(--color-foreground);">Коментарі</h3>
<h3 style="font-size:0.875rem; font-weight:600; color:var(--color-foreground);">{% trans "Комментарии" %}</h3>
<span style="font-size:0.6875rem; background:var(--color-muted); color:var(--color-muted-foreground); border-radius:999px; padding:0.0625rem 0.5rem; font-weight:500;">{{ comments|length }}</span>
</div>
@@ -112,7 +113,7 @@
</div>
</div>
{% empty %}
<div style="padding:1.25rem; text-align:center; color:var(--color-muted-foreground); font-size:0.8125rem;">Коментарів поки немає</div>
<div style="padding:1.25rem; text-align:center; color:var(--color-muted-foreground); font-size:0.8125rem;">{% trans "Комментариев пока нет" %}</div>
{% endfor %}
<!-- Форма коментаря -->
@@ -121,9 +122,9 @@
{% csrf_token %}
<input type="hidden" name="action" value="comment">
<div style="width:2rem; height:2rem; border-radius:50%; background:var(--color-accent); color:var(--color-accent-foreground); display:flex; align-items:center; justify-content:center; font-size:0.625rem; font-weight:700; flex-shrink:0;">{{ request.user|initials }}</div>
<textarea name="text" required placeholder="Написати коментар..."
<textarea name="text" required placeholder="{% trans 'Написать комментарий...' %}"
style="flex:1; min-height:2.5rem; resize:vertical; background:var(--color-muted); border:1px solid var(--color-border); border-radius:var(--radius); padding:0.5rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
<button type="submit" class="btn btn-primary" style="flex-shrink:0;">Надіслати</button>
<button type="submit" class="btn btn-primary" style="flex-shrink:0;">{% trans "Отправить" %}</button>
</form>
</div>
</div>
@@ -134,12 +135,12 @@
{% if is_participant and task.status != 'cancelled' %}
<!-- Дії -->
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); padding:1rem 1.25rem; display:flex; flex-direction:column; gap:0.5rem;">
<h3 style="font-size:0.8125rem; font-weight:600; color:var(--color-foreground); margin-bottom:0.25rem;">Дії</h3>
<h3 style="font-size:0.8125rem; font-weight:600; color:var(--color-foreground); margin-bottom:0.25rem;">{% trans "Действия" %}</h3>
{% if task.status == 'pending' %}
<form hx-post="/tasks/{{ task.pk }}/" hx-target="#main-content" hx-indicator="#loader" style="margin:0;">
{% csrf_token %}
<input type="hidden" name="action" value="status"><input type="hidden" name="status" value="in_progress">
<button type="submit" class="btn btn-primary" style="width:100%; font-size:0.8125rem;">Взяти в роботу</button>
<button type="submit" class="btn btn-primary" style="width:100%; font-size:0.8125rem;">{% trans "Взять в работу" %}</button>
</form>
{% endif %}
{% if task.status != 'done' %}
@@ -152,14 +153,14 @@
<form hx-post="/tasks/{{ task.pk }}/" hx-target="#main-content" hx-indicator="#loader" style="margin:0;">
{% csrf_token %}
<input type="hidden" name="action" value="status"><input type="hidden" name="status" value="pending">
<button type="submit" class="btn btn-secondary" style="width:100%; font-size:0.8125rem;">Повернути в роботу</button>
<button type="submit" class="btn btn-secondary" style="width:100%; font-size:0.8125rem;">{% trans "Вернуть в работу" %}</button>
</form>
{% endif %}
{% if can_edit and task.status != 'done' %}
<form hx-post="/tasks/{{ task.pk }}/" hx-target="#main-content" hx-indicator="#loader" style="margin:0;">
{% csrf_token %}
<input type="hidden" name="action" value="status"><input type="hidden" name="status" value="cancelled">
<button type="submit" class="btn btn-ghost" style="width:100%; font-size:0.8125rem; color:var(--color-muted-foreground);">Скасувати задачу</button>
<button type="submit" class="btn btn-ghost" style="width:100%; font-size:0.8125rem; color:var(--color-muted-foreground);">{% trans "Отменить задачу" %}</button>
</form>
{% endif %}
</div>
@@ -167,7 +168,7 @@
<!-- Учасники -->
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); padding:1rem 1.25rem;">
<h3 style="font-size:0.8125rem; font-weight:600; color:var(--color-foreground); margin-bottom:0.75rem;">Учасники</h3>
<h3 style="font-size:0.8125rem; font-weight:600; color:var(--color-foreground); margin-bottom:0.75rem;">{% trans "Участники" %}</h3>
<div style="display:flex; flex-direction:column; gap:0.875rem;">
{% for role_label, role_people in role_groups %}
{% if role_people %}
@@ -188,7 +189,7 @@
{% endif %}
{% endfor %}
{% if not task.responsible.all and not task.co_executors.all and not task.observers.all %}
<div style="font-size:0.8125rem; color:var(--color-muted-foreground); opacity:0.6;">Не призначено</div>
<div style="font-size:0.8125rem; color:var(--color-muted-foreground); opacity:0.6;">{% trans "Не назначено" %}</div>
{% endif %}
</div>
</div>
@@ -196,16 +197,16 @@
<!-- Інфо -->
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); padding:1rem 1.25rem; display:flex; flex-direction:column; gap:0.625rem;">
<div>
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.04em; margin-bottom:0.125rem;">Автор</div>
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.04em; margin-bottom:0.125rem;">{% trans "Автор" %}</div>
<div style="font-size:0.8125rem; color:var(--color-foreground);">{{ task.creator.get_full_name|default:"—" }}</div>
</div>
<div>
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.04em; margin-bottom:0.125rem;">Створено</div>
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.04em; margin-bottom:0.125rem;">{% trans "Создано" %}</div>
<div style="font-size:0.8125rem; color:var(--color-foreground);">{{ task.created_at|date:"d.m.Y H:i" }}</div>
</div>
{% if task.completed_at %}
<div>
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.04em; margin-bottom:0.125rem;">Виконано</div>
<div style="font-size:0.6875rem; color:var(--color-muted-foreground); text-transform:uppercase; letter-spacing:0.04em; margin-bottom:0.125rem;">{% trans "Выполнено" %}</div>
<div style="font-size:0.8125rem; color:var(--color-foreground);">{{ task.completed_at|date:"d.m.Y H:i" }}</div>
</div>
{% endif %}
+9 -7
View File
@@ -1,3 +1,5 @@
{% load i18n %}
{% trans 'Ответственный' as l_resp %}{% trans '+ Добавить ответственного' as p_resp %}{% trans 'Соисполнители' as l_co %}{% trans '+ Добавить соисполнителя' as p_co %}{% trans 'Наблюдатели' as l_obs %}{% trans '+ Добавить наблюдателя' as p_obs %}
<div class="page-content">
<!-- Назад -->
@@ -10,7 +12,7 @@
</a>
<div style="margin-bottom:1.25rem;">
<h1 style="font-size:1.25rem; font-weight:500; color:var(--color-foreground);">Редагування задачі</h1>
<h1 style="font-size:1.25rem; font-weight:500; color:var(--color-foreground);">{% trans "Редактирование задачи" %}</h1>
</div>
{{ department_tree|json_script:"department-tree-data" }}
@@ -24,14 +26,14 @@
<form hx-post="/tasks/{{ task.pk }}/edit/" hx-target="#main-content" hx-push-url="/tasks/{{ task.pk }}/" hx-indicator="#loader"
style="background:var(--color-card); border:1px solid var(--color-border); border-radius:0.75rem; padding:1.25rem; display:flex; flex-direction:column; gap:0.875rem;">
{% csrf_token %}
<input type="text" name="title" required maxlength="250" value="{{ task.title }}" placeholder="Назва задачі" class="input" style="width:100%; font-weight:500;">
<textarea name="description" placeholder="Опис задачі (необов'язково)..."
<input type="text" name="title" required maxlength="250" value="{{ task.title }}" placeholder="{% trans 'Название задачи' %}" class="input" style="width:100%; font-weight:500;">
<textarea name="description" placeholder="{% trans 'Описание задачи (необязательно)...' %}"
style="width:100%; min-height:5rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;">{{ task.description }}</textarea>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:1rem;">
{% include 'partials/people-picker-field.html' with label='Відповідальний' field_name='responsible' options=employee_options selected_ids=responsible_ids placeholder='+ Додати відповідального' %}
{% include 'partials/people-picker-field.html' with label='Співвиконавці' field_name='co_executors' options=employee_options selected_ids=co_executor_ids placeholder='+ Додати співвиконавця' %}
{% include 'partials/people-picker-field.html' with label='Спостерігачі' field_name='observers' options=employee_options selected_ids=observer_ids placeholder='+ Додати спостерігача' %}
{% include 'partials/people-picker-field.html' with label=l_resp field_name='responsible' options=employee_options selected_ids=responsible_ids placeholder=p_resp %}
{% include 'partials/people-picker-field.html' with label=l_co field_name='co_executors' options=employee_options selected_ids=co_executor_ids placeholder=p_co %}
{% include 'partials/people-picker-field.html' with label=l_obs field_name='observers' options=employee_options selected_ids=observer_ids placeholder=p_obs %}
</div>
<div style="display:flex; align-items:center; gap:1rem; flex-wrap:wrap;">
@@ -41,7 +43,7 @@
{% endfor %}
</select>
<input type="date" name="due_date" value="{{ task.due_date|date:'Y-m-d' }}" class="input" style="width:auto; font-size:0.8125rem;">
<button type="submit" class="btn btn-primary" style="margin-left:auto;">Зберегти зміни</button>
<button type="submit" class="btn btn-primary" style="margin-left:auto;">{% trans "Сохранить изменения" %}</button>
</div>
</form>
<script>initPeoplePickers(document);</script>
+24 -22
View File
@@ -1,10 +1,11 @@
{% load i18n %}
<div class="page-content">
<!-- Заголовок -->
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:1.25rem; gap:0.75rem;">
<div>
<h1 style="font-size:1.25rem; font-weight:500; color:var(--color-foreground);">Мої задачі</h1>
<p style="font-size:0.875rem; color:var(--color-muted-foreground); margin-top:0.25rem;">Задачі, створені вами або призначені вам</p>
<h1 style="font-size:1.25rem; font-weight:500; color:var(--color-foreground);">{% trans "Мои задачи" %}</h1>
<p style="font-size:0.875rem; color:var(--color-muted-foreground); margin-top:0.25rem;">{% trans "Задачи, созданные вами или назначенные вам" %}</p>
</div>
</div>
@@ -22,19 +23,20 @@
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>
</svg>
Нова задача
{% trans "Новая задача" %}
</summary>
<form hx-post="/tasks/" hx-target="#main-content" hx-indicator="#loader"
style="margin-top:0.75rem; background:var(--color-card); border:1px solid var(--color-border); border-radius:0.75rem; padding:1.25rem; display:flex; flex-direction:column; gap:0.875rem;">
{% csrf_token %}
<input type="text" name="title" required maxlength="250" placeholder="Назва задачі" class="input" style="width:100%; font-weight:500;">
<textarea name="description" placeholder="Опис задачі (необов'язково)..."
<input type="text" name="title" required maxlength="250" placeholder="{% trans 'Название задачи' %}" class="input" style="width:100%; font-weight:500;">
<textarea name="description" placeholder="{% trans 'Описание задачи (необязательно)...' %}"
style="width:100%; min-height:5rem; resize:vertical; background:var(--color-card); border:1px solid var(--color-input); border-radius:var(--radius); padding:0.4375rem 0.75rem; font-size:0.875rem; color:var(--color-foreground); font-family:var(--font-sans); outline:none; box-sizing:border-box;"></textarea>
<div style="display:grid; grid-template-columns:1fr 1fr; gap:1rem;">
{% include 'partials/people-picker-field.html' with label='Відповідальний' field_name='responsible' options=employee_options selected_ids=preselect_responsible_ids placeholder='+ Додати відповідального' %}
{% include 'partials/people-picker-field.html' with label='Співвиконавці' field_name='co_executors' options=employee_options selected_ids=empty_ids placeholder='+ Додати співвиконавця' %}
{% include 'partials/people-picker-field.html' with label='Спостерігачі' field_name='observers' options=employee_options selected_ids=empty_ids placeholder='+ Додати спостерігача' %}
{% trans 'Ответственный' as l_resp %}{% trans '+ Добавить ответственного' as p_resp %}{% trans 'Соисполнители' as l_co %}{% trans '+ Добавить соисполнителя' as p_co %}{% trans 'Наблюдатели' as l_obs %}{% trans '+ Добавить наблюдателя' as p_obs %}
<div style="display:grid; grid-template-columns:1fr 1fr; gap:1rem;">
{% include 'partials/people-picker-field.html' with label=l_resp field_name='responsible' options=employee_options selected_ids=preselect_responsible_ids placeholder=p_resp %}
{% include 'partials/people-picker-field.html' with label=l_co field_name='co_executors' options=employee_options selected_ids=empty_ids placeholder=p_co %}
{% include 'partials/people-picker-field.html' with label=l_obs field_name='observers' options=employee_options selected_ids=empty_ids placeholder=p_obs %}
</div>
<div style="display:flex; align-items:center; gap:1rem; flex-wrap:wrap;">
@@ -44,7 +46,7 @@
{% endfor %}
</select>
<input type="date" name="due_date" class="input" style="width:auto; font-size:0.8125rem;">
<button type="submit" class="btn btn-primary" style="margin-left:auto;">Створити задачу</button>
<button type="submit" class="btn btn-primary" style="margin-left:auto;">{% trans "Создать задачу" %}</button>
</div>
</form>
</details>
@@ -55,19 +57,19 @@
{% with base="display:inline-flex; align-items:center; gap:0.375rem; padding:0.375rem 0.75rem; border-radius:calc(var(--radius) - 2px); font-size:0.8125rem; font-weight:500; text-decoration:none; cursor:pointer;" %}
<a href="/tasks/" hx-get="/tasks/" hx-target="#main-content" hx-push-url="/tasks/" hx-indicator="#loader"
style="{{ base }} {% if not active_status %}background:var(--color-primary); color:var(--color-primary-foreground);{% else %}background:transparent; color:var(--color-muted-foreground);{% endif %}">
Всі <span style="background:{% if not active_status %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.all }}</span>
{% trans "Все" %} <span style="background:{% if not active_status %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.all }}</span>
</a>
<a href="/tasks/?status=pending" hx-get="/tasks/?status=pending" hx-target="#main-content" hx-push-url="/tasks/?status=pending" hx-indicator="#loader"
style="{{ base }} {% if active_status == 'pending' %}background:var(--color-primary); color:var(--color-primary-foreground);{% else %}background:transparent; color:var(--color-muted-foreground);{% endif %}">
Очікує <span style="background:{% if active_status == 'pending' %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.pending }}</span>
{% trans "Ожидает" %} <span style="background:{% if active_status == 'pending' %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.pending }}</span>
</a>
<a href="/tasks/?status=in_progress" hx-get="/tasks/?status=in_progress" hx-target="#main-content" hx-push-url="/tasks/?status=in_progress" hx-indicator="#loader"
style="{{ base }} {% if active_status == 'in_progress' %}background:var(--color-primary); color:var(--color-primary-foreground);{% else %}background:transparent; color:var(--color-muted-foreground);{% endif %}">
В роботі <span style="background:{% if active_status == 'in_progress' %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.in_progress }}</span>
{% trans "В работе" %} <span style="background:{% if active_status == 'in_progress' %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.in_progress }}</span>
</a>
<a href="/tasks/?status=done" hx-get="/tasks/?status=done" hx-target="#main-content" hx-push-url="/tasks/?status=done" hx-indicator="#loader"
style="{{ base }} {% if active_status == 'done' %}background:var(--color-primary); color:var(--color-primary-foreground);{% else %}background:transparent; color:var(--color-muted-foreground);{% endif %}">
Виконано <span style="background:{% if active_status == 'done' %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.done }}</span>
{% trans "Выполнено" %} <span style="background:{% if active_status == 'done' %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.done }}</span>
</a>
{% endwith %}
</div>
@@ -99,19 +101,19 @@
<div class="task-meta">
{% if task.status == 'done' %}
<span style="display:inline-flex; align-items:center; gap:0.25rem; font-size:0.75rem; color:hsl(152 55% 35%);">
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>Виконано
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>{% trans "Выполнено" %}
</span>
{% elif task.status == 'in_progress' %}
<span style="display:inline-flex; align-items:center; gap:0.25rem; font-size:0.75rem; color:hsl(152 55% 35%);">
<span style="width:6px; height:6px; border-radius:50%; background:hsl(152 55% 45%); flex-shrink:0;"></span>В роботі
<span style="width:6px; height:6px; border-radius:50%; background:hsl(152 55% 45%); flex-shrink:0;"></span>{% trans "В работе" %}
</span>
{% elif task.status == 'cancelled' %}
<span style="display:inline-flex; align-items:center; gap:0.25rem; font-size:0.75rem; color:var(--color-muted-foreground);">
<span style="width:6px; height:6px; border-radius:50%; background:var(--color-muted-foreground); flex-shrink:0;"></span>Скасовано
<span style="width:6px; height:6px; border-radius:50%; background:var(--color-muted-foreground); flex-shrink:0;"></span>{% trans "Отменено" %}
</span>
{% else %}
<span style="display:inline-flex; align-items:center; gap:0.25rem; font-size:0.75rem; color:hsl(38 70% 35%);">
<span style="width:6px; height:6px; border-radius:50%; background:hsl(38 92% 50%); flex-shrink:0;"></span>Очікує
<span style="width:6px; height:6px; border-radius:50%; background:hsl(38 92% 50%); flex-shrink:0;"></span>{% trans "Ожидает" %}
</span>
{% endif %}
{% if task.due_date %}
@@ -122,15 +124,15 @@
<span class="badge {{ task.priority_badge }}">{{ task.get_priority_display }}</span>
{% if task.can_edit %}
<a hx-get="/tasks/{{ task.pk }}/edit/" hx-target="#main-content" hx-push-url="/tasks/{{ task.pk }}/edit/" hx-indicator="#loader"
class="btn btn-ghost btn-icon" title="Редагувати" style="padding:0.25rem; color:var(--color-muted-foreground); margin-left:auto; cursor:pointer;">
class="btn btn-ghost btn-icon" title="{% trans 'Редактировать' %}" style="padding:0.25rem; color:var(--color-muted-foreground); margin-left:auto; cursor:pointer;">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
</a>
{% endif %}
{% if task.can_delete %}
<form hx-post="/tasks/{{ task.pk }}/delete/" hx-target="#main-content" hx-push-url="/tasks/" hx-indicator="#loader"
hx-confirm="Видалити задачу «{{ task.title }}»?" style="margin:0; display:flex;">
hx-confirm="{% trans 'Удалить задачу' %} «{{ task.title }}»?" style="margin:0; display:flex;">
{% csrf_token %}
<button type="submit" class="btn btn-ghost btn-icon" title="Видалити" style="padding:0.25rem; color:var(--color-muted-foreground);">
<button type="submit" class="btn btn-ghost btn-icon" title="{% trans 'Удалить' %}" style="padding:0.25rem; color:var(--color-muted-foreground);">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/></svg>
</button>
</form>
@@ -139,7 +141,7 @@
</div>
{% empty %}
<div style="padding:2.5rem; text-align:center; color:var(--color-muted-foreground); font-size:0.875rem;">
{% if active_status %}Задач з таким статусом немає{% else %}Задач поки немає — створіть першу{% endif %}
{% if active_status %}{% trans "Задач с таким статусом нет" %}{% else %}{% trans "Задач пока нет — создайте первую" %}{% endif %}
</div>
{% endfor %}