скрыть начало и конец
Gitea Actions Demo / build_and_push (push) Successful in 1m18s Details

This commit is contained in:
artem 2026-09-25 09:57:55 +03:00
parent e59523fd1c
commit 72b786994d
9 changed files with 65 additions and 2 deletions

View File

@ -2,12 +2,23 @@
## Task State ## Task State
- task_id: TASK-HIDE-TRACK-T1 - task_id: TASK-HIDE-TRACK-3-FIX
- status: success - status: success
- parent_task: TASK-HIDE-TRACK - parent_task: TASK-HIDE-TRACK
- summary: **Backend тест `test_workout_hide_start_end` добавлен. Все 4 теста PASSED (5.13s).** - summary: **Чекбокс `hide_start_end` + `changeHideStartEnd` + i18n ключ восстановлены в WorkoutItem.vue (потеряны в git stash при TASK-HIDE-TRACK-4).**
- next task: — - next task: —
## ✅ CODER SUCCESS REPORT — TASK-HIDE-TRACK-3-FIX
- `src/pages/workouts/components/WorkoutItem.vue`:
- импорт `import { useI18n } from "vue-i18n"` + `const { t } = useI18n();` (рядом с `useToast`).
- template: чекбокс `hide_start_end` (v-model + `v-on:change="changeHideStartEnd(...)"`) после блока `is_public`.
- script: `changeHideStartEnd(value: boolean)` → `axiosAuth.patch('/api/v0/workouts/${workoutItem.id}', { hide_start_end: value })` (с guard `!workoutItem` и catch-тостом, как у `changePublic`).
- i18n: ключ `workout.hide_start_end` добавлен во ВСЕ 6 локали (`br, cn, es, gb, ir, ru`) — ранее отсутствовал (секция `workout` была создана заново).
- Verified: `yarn build` exit 0 (vue-tsc --noEmit 0 ошибок, vite ✓).
- Verified: `grep hide_start_end` → 4 совпадения; `grep useI18n` → 2 совпадения.
- Note: `yarn lint` сломан системно — `tsutils.iterateComments is not a function` на всех .vue файлах (существующий дефект окружения, не от этих изменений).
## ✅ CODER SUCCESS REPORT — TASK-HIDE-TRACK-T1 ## ✅ CODER SUCCESS REPORT — TASK-HIDE-TRACK-T1
- `../backend/tests/test_api_workout.py`: добавлен `test_workout_hide_start_end` — проверяет PATCH `hide_start_end` (False→True→False) с GET-верификацией на каждом шаге. - `../backend/tests/test_api_workout.py`: добавлен `test_workout_hide_start_end` — проверяет PATCH `hide_start_end` (False→True→False) с GET-верификацией на каждом шаге.

View File

@ -1,5 +1,15 @@
# Progress — Strava Frontend # Progress — Strava Frontend
## 2026-09-25 — TASK-HIDE-TRACK-3-FIX: восстановление чекбокса hide_start_end в WorkoutItem.vue
- `src/pages/workouts/components/WorkoutItem.vue` — восстановлены (потеряны в git stash при TASK-HIDE-TRACK-4):
- `import { useI18n } from "vue-i18n"` + `const { t } = useI18n();`
- template: чекбокс `hide_start_end` после блока `is_public`
- `changeHideStartEnd(value: boolean)` → PATCH `hide_start_end` (guard + catch-тост, паттерн `changePublic`)
- i18n: секция `workout` + ключ `hide_start_end` добавлены во все 6 локалей (`br, cn, es, gb, ir, ru`) — секция отсутствовала.
- Verified: `yarn build` exit 0 (vue-tsc 0 errors, vite ✓ 7.09s).
- Known issue: `yarn lint` сломан системно — `tsutils.iterateComments is not a function` (дефект окружения).
## 2026-09-25 — TASK-HIDE-TRACK-B3: hide_start_end в PATCH endpoint + service (backend) ## 2026-09-25 — TASK-HIDE-TRACK-B3: hide_start_end в PATCH endpoint + service (backend)
- `../backend/app/web/v0/workout.py` — `WorkoutEditReq` + `hide_start_end: bool | None = Field(None)`; PATCH `/workouts/{workout_id}` передаёт `hide_start_end=req.hide_start_end` в `workout_service.workout_edit(...)`. - `../backend/app/web/v0/workout.py` — `WorkoutEditReq` + `hide_start_end: bool | None = Field(None)`; PATCH `/workouts/{workout_id}` передаёт `hide_start_end=req.hide_start_end` в `workout_service.workout_edit(...)`.

View File

@ -157,5 +157,8 @@
"undo": "Desfazer", "undo": "Desfazer",
"dropzone": "Arraste arquivos aqui para enviar", "dropzone": "Arraste arquivos aqui para enviar",
"fileDeleted": "Arquivo excluído" "fileDeleted": "Arquivo excluído"
},
"workout": {
"hide_start_end": "Ocultar início e fim da trilha"
} }
} }

View File

@ -190,5 +190,8 @@
"undo": "撤销", "undo": "撤销",
"dropzone": "将文件拖放到此处进行上传", "dropzone": "将文件拖放到此处进行上传",
"fileDeleted": "文件已删除" "fileDeleted": "文件已删除"
},
"workout": {
"hide_start_end": "隐藏轨迹起点和终点"
} }
} }

View File

@ -146,5 +146,8 @@
"undo": "Deshacer", "undo": "Deshacer",
"dropzone": "Arrastra archivos aquí para subir", "dropzone": "Arrastra archivos aquí para subir",
"fileDeleted": "Archivo eliminado" "fileDeleted": "Archivo eliminado"
},
"workout": {
"hide_start_end": "Ocultar inicio y fin de la ruta"
} }
} }

View File

@ -183,5 +183,8 @@
"undo": "Undo", "undo": "Undo",
"dropzone": "Drop files here to upload", "dropzone": "Drop files here to upload",
"fileDeleted": "File deleted" "fileDeleted": "File deleted"
},
"workout": {
"hide_start_end": "Hide start and end of track"
} }
} }

View File

@ -198,5 +198,8 @@
"undo": "واگرد", "undo": "واگرد",
"dropzone": "فایل‌ها را برای بارگذاری اینجا رها کنید", "dropzone": "فایل‌ها را برای بارگذاری اینجا رها کنید",
"fileDeleted": "فایل حذف شد" "fileDeleted": "فایل حذف شد"
},
"workout": {
"hide_start_end": "پنهان کردن شروع و پایان مسیر"
} }
} }

View File

@ -187,5 +187,8 @@
"undo": "Отменить", "undo": "Отменить",
"dropzone": "Перетащите файл сюда для загрузки", "dropzone": "Перетащите файл сюда для загрузки",
"fileDeleted": "Файл удалён" "fileDeleted": "Файл удалён"
},
"workout": {
"hide_start_end": "Скрыть начало и конец трека"
} }
} }

View File

@ -176,6 +176,14 @@
v-on:change="changePublic(workoutItem.is_public)" v-on:change="changePublic(workoutItem.is_public)"
/> />
</div> </div>
<div class="workout-item-params" v-if="isPrivate">
<div class="workout-item-params-name">{{ t("workout.hide_start_end") }}:&nbsp;</div>
<input
type="checkbox"
v-model="workoutItem.hide_start_end"
v-on:change="changeHideStartEnd(workoutItem.hide_start_end)"
/>
</div>
<div class="workout-item-params" v-if="dzenLink || isPrivate"> <div class="workout-item-params" v-if="dzenLink || isPrivate">
<div class="workout-item-params-name">Ссылки на описание:&nbsp;</div> <div class="workout-item-params-name">Ссылки на описание:&nbsp;</div>
<div v-if="dzenLink"> <div v-if="dzenLink">
@ -429,6 +437,7 @@ import {
watch, watch,
} from "vue"; } from "vue";
import { useToast, useForm } from "vuestic-ui/web-components"; import { useToast, useForm } from "vuestic-ui/web-components";
import { useI18n } from "vue-i18n";
import zoomPlugin from "chartjs-plugin-zoom"; import zoomPlugin from "chartjs-plugin-zoom";
import { import {
Chart as ChartJS, Chart as ChartJS,
@ -551,6 +560,7 @@ ChartJS.register(
TimeScale, TimeScale,
); );
const { init } = useToast(); const { init } = useToast();
const { t } = useI18n();
function isEmpty(obj: Record<string, unknown>) { function isEmpty(obj: Record<string, unknown>) {
for (const prop in obj) { for (const prop in obj) {
@ -1205,6 +1215,20 @@ const changePublic = (value: boolean) => {
}); });
}); });
}; };
const changeHideStartEnd = (value: boolean) => {
if (!workoutItem) {
return;
}
axiosAuth
.patch(`/api/v0/workouts/${workoutItem.id}`, { hide_start_end: value })
.then((_response: AxiosResponse) => {})
.catch((_error: AxiosError) => {
init({
message: "Что-то пошло не так.",
color: "error",
});
});
};
const fileInput = ref<HTMLInputElement | null>(null); const fileInput = ref<HTMLInputElement | null>(null);
const uploading = ref(false); const uploading = ref(false);