diff --git a/frontend/src/app/tasks/page.tsx b/frontend/src/app/tasks/page.tsx
index 04d9bfd2..00714f0a 100644
--- a/frontend/src/app/tasks/page.tsx
+++ b/frontend/src/app/tasks/page.tsx
@@ -11389,10 +11389,11 @@ function TasksPageContent() {
setChecklistTemplateTarget("view");
setChecklistTemplatesOpen(true);
}}
- className="app-action-secondary inline-flex h-8 shrink-0 items-center gap-1 rounded-lg px-2 text-xs"
- title="Шаблоны чек-листов"
+ className="app-icon-button flex h-8 w-8 shrink-0 items-center justify-center rounded-lg"
+ title="Открыть шаблоны чек-листов"
+ aria-label="Открыть шаблоны чек-листов"
>
- Шаблоны
+
{checklistBadgeTotal > 0 ? (
- Шаблоны
+
) : displayed.length === 0 ? (
- Пока нет опубликованных шаблонов.
+ {tab === "personal"
+ ? "У вас пока нет шаблонов. Создайте первый."
+ : "В этом разделе пока нет шаблонов."}
) : (
displayed.map((template) => (
@@ -538,15 +796,23 @@ export default function TaskChecklistTemplatesModal({
onClick={() => void apply(template)}
className="app-action-primary rounded-lg px-3 py-2 text-xs disabled:opacity-50"
>
- Добавить в чек-лист
+ Применить
) : null}
- {tab === "personal" && boardId ? (
+ {tab === "personal" && boards.length > 0 ? (
void propose(template)}
- className="app-action-secondary inline-flex items-center gap-1 rounded-lg px-3 py-2 text-xs disabled:opacity-50"
+ onClick={() => {
+ setProposingId((current) =>
+ current === template.id ? null : template.id,
+ );
+ setProposalBoardId(
+ currentBoardId ?? boards[0]?.id ?? null,
+ );
+ }}
+ className="app-action-secondary inline-flex items-center gap-1.5 rounded-lg px-3 py-2 text-xs disabled:opacity-50"
+ aria-expanded={proposingId === template.id}
>
Предложить на доску
@@ -579,6 +845,47 @@ export default function TaskChecklistTemplatesModal({
История
+ {tab === "personal" && proposingId === template.id ? (
+
+
+
+ void propose(template, proposalBoardId)}
+ className="app-action-primary rounded-lg px-3 py-2 text-xs disabled:opacity-50"
+ >
+ Отправить
+
+ setProposingId(null)}
+ className="app-action-secondary rounded-lg px-3 py-2 text-xs"
+ >
+ Отмена
+
+
+
+ ) : null}
{openVersions === template.id ? (
{(versions[template.id] || []).map((version) => (
@@ -661,63 +968,71 @@ export default function TaskChecklistTemplatesModal({
) : null}
{tab === "board" && rights?.is_owner ? (
-
-
- Редакторы шаблонов доски
-
-
- Назначение редактора даёт право публиковать и менять шаблоны этой
- доски, но не расширяет доступ к задачам.
-
- {rights.editor_ids.map((id) => (
-
-
{userLabel(id)}
+
+
+
+ Редакторы шаблонов доски
+
+ {rights.editor_ids.length}
+
+
+
+
+ Назначение редактора даёт право публиковать и менять шаблоны
+ этой доски, но не расширяет доступ к задачам.
+
+ {rights.editor_ids.map((id) => (
+
+ {userLabel(id)}
+ void setEditor(id, false)}
+ className="app-action-danger rounded-lg px-2 py-1.5"
+ >
+ Отозвать
+
+
+ ))}
+
+
void setEditor(id, false)}
- className="app-action-danger rounded-lg px-2 py-1.5"
+ disabled={busy || !newEditorId}
+ onClick={() =>
+ newEditorId && void setEditor(newEditorId, true)
+ }
+ className="app-action-primary rounded-lg px-3 py-2 text-xs"
>
- Отозвать
+ Назначить
- ))}
-
-
- newEditorId && void setEditor(newEditorId, true)}
- className="app-action-primary rounded-lg px-3 py-2 text-xs"
- >
- Назначить
-
-
+
) : null}
{canApply ? (