diff --git a/docs/TZ.md b/docs/TZ.md
index 6c34b79..03a4088 100644
--- a/docs/TZ.md
+++ b/docs/TZ.md
@@ -4,7 +4,7 @@
| | |
|---|---|
-| Версия ТЗ | 0.81 |
+| Версия ТЗ | 0.82 |
| Дата | 2026-10-10 |
| Статус | На обсуждении |
@@ -232,6 +232,18 @@
1px и прижат к низу карточки, поэтому в сетке списка он у всех карточек на одной
линии. Иконка рядом с текстом идёт с китовым классом `normalize` — без него глиф
иконочного шрифта садится на 1.7px выше середины строки.
+- **Проект задачи — из меню карточки** (0.82): в «⋯»-меню карточки задачи рядом стоят
+ «Перейти к проекту» и «Переместить в проект» — это один и тот же вопрос «в каком
+ проекте задача». «Перейти» показывается у задачи с проектом и **не показывается на
+ странице самого проекта** (там задача и так лежит в нём). «Переместить» открывает
+ модалку с выбором проекта: `GnSelect` кита, первым пунктом «— без проекта —»,
+ текущий проект выбран по умолчанию; задача в **архивном** проекте тоже остаётся
+ выбранной, хотя в справочнике активных проектов её нет. Перенос уходит тем же
+ `PATCH /api/tasks/{id}` с `project_id`, что и правка поля «Проект» на странице задачи:
+ бэкенд проверяет, что проект принадлежит пользователю, и рассылает `task.changed`.
+ **XP и монеты за перенос не начисляются** — они висят только на переходе в
+ «завершено». Успех подтверждается тостом, список перечитывается сразу (`moved`),
+ поэтому задача тут же уходит со страницы прежнего проекта.
### 3.7. Главная страница (дашборд + стек)
@@ -989,6 +1001,28 @@
отсчёта срока иконка шла без китового класса `normalize`, глиф иконочного шрифта
садился выше середины строки и читался подвешенным — как в карточке задачи, где
этот класс стоит с 0.76.
+- **Карточки проекта и задачи различаются корешком** (0.82): карточки двух сущностей
+ выглядели одинаково — та же панель с рамкой 2px, тот же подвал, — и в списке не
+ читалось, что перед тобой папка с задачами, а не сама задача. Теперь у **карточки
+ проекта левая грань 6px** (китовый `--gn-border-width-accent`, тот же шаг, что у
+ полосы шапки страницы) и **цвета проекта** — того же, что метка у имени и заливка
+ прогресса; у проекта без цвета грань берёт акцент кита, как и его прогресс. У
+ карточки задачи рамка осталась ровной 2px, у задачи без изменений. Тот же корешок
+ у карточки проекта в архиве и у заготовок списков (иначе при загрузке карточка
+ дёрнула бы ширину содержимого). Наведение подкрашивает рамку, но **не корешок**:
+ цвет грани — принадлежность проекту, а не состояние карточки.
+- **Пустой подвал карточки проекта говорит «без активности»** (0.82): у проекта без
+ задач активности по задачам нет, и подвал оставался пустой полосой — читалось как
+ недоделка. Теперь на месте свежести стоит «без активности» (ключ `projects.noActivity`).
+- **Полоса прокрутки спрятана у всех табов** (0.82): правило было только у табов-
+ фильтра «Списка задач», поэтому на странице проекта табы статуса оставались с
+ полосой; теперь оно общее для `.tabs-list` в `kit-overrides.css`. Прокрутка
+ сохранена (0.80).
+- **Модалка выбора проекта при переносе** (0.82): собрана на публичных `GnModal` +
+ `GnSelect` кита, с подписью, какая именно задача переезжает. Акцент отдан действию
+ («Переместить»), а «Отмена» осталась контурной: в прочих диалогах приложения действие
+ красится в `danger`/`success`, а `primary` берёт на себя отмена — у переноса своего
+ смыслового варианта нет.
- **Кнопка «назад» над шапкой страницы** (0.70): выйти с любой страницы можно было
только через меню разделов, возврата в приложении не было. Теперь над шапкой
страницы, на каждой странице, стоит **стрелка назад** — но только если в истории
diff --git a/frontend/src/components/TaskCard.vue b/frontend/src/components/TaskCard.vue
index ab4f3fd..559c42d 100644
--- a/frontend/src/components/TaskCard.vue
+++ b/frontend/src/components/TaskCard.vue
@@ -1,15 +1,19 @@
+
+
+
+
+
+
+
+ {{ t('common.move') }}
+
+ {{ t('common.cancel') }}
+
+
+
+
+
diff --git a/frontend/src/kit-overrides.css b/frontend/src/kit-overrides.css
index da1c976..6fb1b3a 100644
--- a/frontend/src/kit-overrides.css
+++ b/frontend/src/kit-overrides.css
@@ -93,6 +93,20 @@
border-radius: 999px;
}
+/* --- Полоса прокрутки у табов (0.80, общее правило с 0.82) --- */
+/* Ряд табов прокручивается по горизонтали (у кита .tabs-list{overflow-x:auto}),
+ но видимая полоса тут только шумит: обрезанный крайний таб и так читается как
+ «дальше есть». Прячем у всех табов сразу — правило было только у фильтра списка
+ задач, а табы статуса на странице проекта оставались с полосой. Скролл остаётся.
+ `scrollbar-width: none` достаточно Chromium и Firefox; `::-webkit-scrollbar`
+ держим для Safari — там первое свойство не поддерживается */
+.tabs-list {
+ scrollbar-width: none;
+}
+.tabs-list::-webkit-scrollbar {
+ display: none;
+}
+
/* --- Подвал карточки (0.76, отступы выровнены в 0.81) --- */
/* У кита `.card .card-footer` — просто полоса с отступами: ни границы, ни
раскладки, ни своего размера (flex/13px есть только у горизонтального
diff --git a/frontend/src/locales/en.ts b/frontend/src/locales/en.ts
index 843dae5..9536edf 100644
--- a/frontend/src/locales/en.ts
+++ b/frontend/src/locales/en.ts
@@ -16,6 +16,7 @@
confirmTitle: 'Confirmation',
delete: 'Delete',
open: 'Open',
+ move: 'Move',
actions: 'Actions',
expand: 'Expand',
collapse: 'Collapse',
@@ -361,6 +362,13 @@
createdRaw: 'Task went to the stack — detail it there',
actions: 'Actions',
addTag: 'Add a tag…',
+ // Проект задачи в меню карточки (0.82): перейти к проекту и перенести
+ // в другой — соседние пункты, это один вопрос «в каком проекте задача»
+ goToProject: 'Go to project',
+ moveToProject: 'Move to project',
+ moveHint: 'Task "{title}" will move to the selected project',
+ moved: 'Task moved to "{project}"',
+ movedOut: 'Task taken out of its project',
},
projectPage: {
notFoundTitle: 'Project not found',
@@ -429,6 +437,7 @@
overdue: '{n} overdue',
nextDeadline: 'Next deadline: {date}',
lastActivity: 'Last task activity: {date}',
+ noActivity: 'No activity',
colorNone: 'No color',
sitePlaceholder: 'https://example.com',
repositoryPlaceholder: 'https://git.example.com/owner/repo',
diff --git a/frontend/src/locales/ru.ts b/frontend/src/locales/ru.ts
index 78b37de..db07780 100644
--- a/frontend/src/locales/ru.ts
+++ b/frontend/src/locales/ru.ts
@@ -17,6 +17,7 @@
confirmTitle: 'Подтверждение',
delete: 'Удалить',
open: 'Открыть',
+ move: 'Переместить',
actions: 'Действия',
expand: 'Развернуть',
collapse: 'Свернуть',
@@ -361,6 +362,13 @@
createdRaw: 'Задача попала в стек — детализируйте её там',
actions: 'Действия',
addTag: 'Добавить тег…',
+ // Проект задачи в меню карточки (0.82): перейти к проекту и перенести
+ // в другой — соседние пункты, это один вопрос «в каком проекте задача»
+ goToProject: 'Перейти к проекту',
+ moveToProject: 'Переместить в проект',
+ moveHint: 'Задача «{title}» уедет в выбранный проект',
+ moved: 'Задача перенесена в «{project}»',
+ movedOut: 'Задача вынута из проекта',
},
projectPage: {
notFoundTitle: 'Проект не найден',
@@ -433,6 +441,7 @@
overdue: 'просрочено {n}',
nextDeadline: 'Ближайший дедлайн: {date}',
lastActivity: 'Последняя активность по задачам: {date}',
+ noActivity: 'без активности',
colorNone: 'Без цвета',
sitePlaceholder: 'https://example.com',
repositoryPlaceholder: 'https://git.example.com/owner/repo',
diff --git a/frontend/src/locales/uk.ts b/frontend/src/locales/uk.ts
index 5337864..b7ac8ca 100644
--- a/frontend/src/locales/uk.ts
+++ b/frontend/src/locales/uk.ts
@@ -16,6 +16,7 @@
confirmTitle: 'Підтвердження',
delete: 'Видалити',
open: 'Відкрити',
+ move: 'Перемістити',
actions: 'Дії',
expand: 'Розгорнути',
collapse: 'Згорнути',
@@ -361,6 +362,13 @@
createdRaw: 'Завдання потрапило у стек — деталізуйте його там',
actions: 'Дії',
addTag: 'Додати теґ…',
+ // Проєкт задачі в меню картки (0.82): перейти до проєкту й перенести
+ // в інший — сусідні пункти, це одне питання «у якому проєкті задача»
+ goToProject: 'Перейти до проєкту',
+ moveToProject: 'Перемістити до проєкту',
+ moveHint: 'Завдання «{title}» переїде до вибраного проєкту',
+ moved: 'Завдання перенесено до «{project}»',
+ movedOut: 'Завдання вилучено з проєкту',
},
projectPage: {
notFoundTitle: 'Проєкт не знайдено',
@@ -429,6 +437,7 @@
overdue: 'прострочено {n}',
nextDeadline: 'Найближчий дедлайн: {date}',
lastActivity: 'Остання активність за задачами: {date}',
+ noActivity: 'без активності',
colorNone: 'Без кольору',
sitePlaceholder: 'https://example.com',
repositoryPlaceholder: 'https://git.example.com/owner/repo',
diff --git a/frontend/src/views/ArchiveView.vue b/frontend/src/views/ArchiveView.vue
index 66ca11b..785ad29 100644
--- a/frontend/src/views/ArchiveView.vue
+++ b/frontend/src/views/ArchiveView.vue
@@ -141,7 +141,12 @@
/>
-
+
{{ project.name }}
@@ -196,6 +201,15 @@
.card-link:hover {
color: var(--accent, #7aa2f7);
}
+/* Корешок проекта (0.82): тот же признак, что у карточек на странице проектов
+ (ProjectsView) — левая грань 6px и цвета проекта. Архив тоже показывает
+ проекты, и они должны читаться как проекты, а не как задачи. Заготовке
+ достаётся акцент кита: цвета у неё ещё нет */
+.archive-card,
+.list-skeleton .card {
+ border-left-width: var(--gn-border-width-accent, 6px);
+ border-left-color: var(--card-color, var(--gn-color-secondary, #7aa2f7));
+}
.list-skeleton {
margin-bottom: 1rem;
display: flex;
diff --git a/frontend/src/views/ListView.vue b/frontend/src/views/ListView.vue
index 40dd02c..8b7b880 100644
--- a/frontend/src/views/ListView.vue
+++ b/frontend/src/views/ListView.vue
@@ -263,6 +263,7 @@
show-project
@status-change="setStatus"
@delete="askDelete"
+ @moved="load"
/>
@@ -291,17 +292,6 @@
max-width: 100%;
margin-bottom: 1.25rem;
}
-/* Полосу прокрутки у табов прячем (0.80): ряд прокручивается по горизонтали
- (у кита .tabs-list{overflow-x:auto}), но видимая полоса тут только шумит —
- обрезанный шестой таб и так читается как «дальше есть». Скролл остаётся.
- `scrollbar-width: none` достаточно Chromium и Firefox; `::-webkit-scrollbar`
- держим для Safari — там первое свойство не поддерживается */
-.filter-tabs :deep(.tabs-list) {
- scrollbar-width: none;
-}
-.filter-tabs :deep(.tabs-list)::-webkit-scrollbar {
- display: none;
-}
/* Фильтры в шапке (0.75): переключатель и поле тега — одной группой справа от
заголовка. Свой gap вместо китовских 8px у .page-header-actions: подпись
переключателя липла к коробке поля. Группа переносится по строкам на узком
diff --git a/frontend/src/views/OptionsView.vue b/frontend/src/views/OptionsView.vue
index 375bb3c..338394d 100644
--- a/frontend/src/views/OptionsView.vue
+++ b/frontend/src/views/OptionsView.vue
@@ -125,6 +125,7 @@
:link-query="{ via: 'options' }"
@status-change="setStatus"
@delete="askDelete"
+ @moved="fetchOptions"
/>
diff --git a/frontend/src/views/ProjectView.vue b/frontend/src/views/ProjectView.vue
index fee803b..6611db0 100644
--- a/frontend/src/views/ProjectView.vue
+++ b/frontend/src/views/ProjectView.vue
@@ -999,6 +999,7 @@
:show-project="false"
@status-change="setStatus"
@delete="askDelete"
+ @moved="load"
/>
diff --git a/frontend/src/views/ProjectsView.vue b/frontend/src/views/ProjectsView.vue
index 3748432..c80e87e 100644
--- a/frontend/src/views/ProjectsView.vue
+++ b/frontend/src/views/ProjectsView.vue
@@ -170,9 +170,10 @@
deadlineTitle: stats.nextDeadline
? t('projects.nextDeadline', { date: formatDate(stats.nextDeadline) })
: '',
- // Свежесть (0.69): подвал карточки есть всегда, поэтому в проекте без задач
- // строка пустая (активности по задачам там нет); полная дата — в подсказке
- activityAgo: timeAgo(stats.activity),
+ // Свежесть (0.69): подвал карточки есть всегда, поэтому у проекта без задач
+ // (активности по задачам там нет) вместо пустой строки — «без активности»
+ // (0.82): пустая полоса выглядела недоделкой. Полная дата — в подсказке
+ activityAgo: timeAgo(stats.activity) || t('projects.noActivity'),
activityTitle: stats.activity
? t('projects.lastActivity', {
date: formatDate(new Date(stats.activity).toISOString()),
@@ -402,7 +403,7 @@
так подвал отделён чертой во всю ширину карточки, как в карточке
задачи (общая полоса — в kit-overrides.css) -->
-
+
{{ row.activityAgo }}
@@ -514,11 +515,19 @@
/* Выравнивание подвала (0.66): карточка — колонка на всю высоту трека,
содержимое забирает свободное место, подвал прижимается к низу.
height: auto у .card-content обязателен: у кита там height: 100%, и на
- растянутой карточке содержимое переполнялось бы на высоту шапки */
+ растянутой карточке содержимое переполнялось бы на высоту шапки.
+ Корешок (0.82): у карточки проекта левая грань в 6px (китовый
+ --gn-border-width-accent — тот же шаг, что у полосы .page-header) и цвета
+ проекта, того же, что метка у имени и заливка прогресса. У карточки задачи
+ рамка остаётся ровной, 2px: по одной этой грани видно, что перед тобой папка
+ с задачами, а не сама задача. Проекту без цвета достаётся акцент кита —
+ ровно как заливке его прогресса */
.card-wrap :deep(.card) {
display: flex;
flex-direction: column;
height: 100%;
+ border-left-width: var(--gn-border-width-accent, 6px);
+ border-left-color: var(--card-color, var(--gn-color-secondary, #7aa2f7));
}
.card-wrap :deep(.card-content) {
display: flex;
@@ -527,8 +536,12 @@
height: auto;
min-height: 0;
}
+/* Наведение подкрашивает рамку, но не корешок: цвет левой грани — это
+ принадлежность проекту, а не состояние карточки */
.project-card:hover :deep(.card) {
- border-color: var(--accent, #7aa2f7);
+ border-top-color: var(--accent, #7aa2f7);
+ border-right-color: var(--accent, #7aa2f7);
+ border-bottom-color: var(--accent, #7aa2f7);
}
.project-card:focus-visible {
outline: 2px solid var(--accent, #7aa2f7);
@@ -572,12 +585,16 @@
margin-bottom: 1rem;
}
/* карточка-скелет: как реальная карточка проекта — тянется на ширину трека
- и на высоту ряда, содержимое колонкой (0.66 — подвал скелета внизу) */
+ и на высоту ряда, содержимое колонкой (0.66 — подвал скелета внизу).
+ Корешок (0.82) — сразу и в заготовке: иначе при загрузке карточка дёрнула бы
+ ширину содержимого. Цвет — акцент кита: у заготовки проекта ещё нет */
.list-skeleton .card {
display: flex;
flex-direction: column;
width: 100%;
max-width: none;
+ border-left-width: var(--gn-border-width-accent, 6px);
+ border-left-color: var(--gn-color-secondary, #7aa2f7);
}
.list-skeleton .card-content {
display: flex;
diff --git a/frontend/src/views/TaskView.vue b/frontend/src/views/TaskView.vue
index 5c576fb..a3b07b5 100644
--- a/frontend/src/views/TaskView.vue
+++ b/frontend/src/views/TaskView.vue
@@ -861,6 +861,7 @@
:task="child"
@status-change="setStatus"
@delete="askDelete"
+ @moved="load"
/>