[F8-02] Навигация по ходам: no-op на ходе 0 #45

Closed
opened 2026-05-25 21:40:19 +00:00 by owner · 5 comments
Collaborator

Подзадача полировки UI (этап F8), родительский #43.

Цель: Клик по «current» в навигации по ходам при текущем ходе = 0 не должен дёргать бэкенд и перерисовывать UI.

Пункты из #43:

7. В режиме игры. Когда текущий номер хода = 0, нажатие на "current"-элемент выпадающего списка в верхней навигации по ходам вызывает запрос к бэкенду и перерисовку UI. В этом нет никакого смысла.

Заметка. Чистый no-op, когда выбранный текущий ход уже активен (ход 0).


Порядок обработки: F8-02 из 12. Создано в рамках #43; зонтичный issue остаётся открытым до закрытия всех подзадач.

Подзадача полировки UI (этап **F8**), родительский #43. **Цель:** Клик по «current» в навигации по ходам при текущем ходе = 0 не должен дёргать бэкенд и перерисовывать UI. **Пункты из #43:** > **7.** В режиме игры. Когда текущий номер хода = 0, нажатие на "current"-элемент выпадающего списка в верхней навигации по ходам вызывает запрос к бэкенду и перерисовку UI. В этом нет никакого смысла. _Заметка._ Чистый no-op, когда выбранный текущий ход уже активен (ход 0). --- _Порядок обработки: **F8-02** из 12. Создано в рамках #43; зонтичный issue остаётся открытым до закрытия всех подзадач._
owner added the Kind/Bug
Priority
Low
4
ready
labels 2026-05-25 21:40:19 +00:00
developer was assigned by owner 2026-05-25 21:40:19 +00:00
developer added
claude
working
and removed ready labels 2026-05-25 22:13:41 +00:00
Author
Collaborator

@developer Кая! тут no-op не на "ходе 0", а не любом ходе, который текущий, то есть выбран в игровом UI! Это важно :)

@developer Кая! тут no-op не на "ходе 0", а не любом ходе, который текущий, то есть выбран в игровом UI! Это важно :)
Owner
Working log (issue-agent) — click to expand

State: done
Updated: 2026-05-26T05:14Z
Branch / PR: feature/issue-45-turn-navigator-noop → PR #57 MERGED into development at 1f6791549a25e014370744c44d0fcc896aeb76a0

Merge gate passed (this run):

  • PR mergeable, base development, body contains Closes #45.
  • CI green for head e82c9f8b: ui-test push (run 346) success, ui-test pull_request (run 347) success, dev-deploy (run 348) success. Combined commit-status carried the known phantom pending on the push context — workflow run conclusions are authoritative.
  • APPROVED review by issue author (owner, review id 6), stale: false, commit_id == e82c9f8b… (current head).
  • Zero PR-level comments, zero review-line comments — no threads to resolve.
  • Issue #45 was open at merge time — no cancel signal.

Post-merge: Closes #45 auto-closed the issue at 2026-05-26T05:13:24Z; set claude/done (the exclusive claude/* scope cleared claude/in-review). Owner's confirmation comment (335) acknowledged before merge.

Shipped: guard if (turn === gameState.viewedTurn) return; in ui/frontend/src/lib/header/turn-navigator.svelte::goToTurn — re-clicking the on-screen turn closes the popover and stops. Same fix incidentally drops the redundant re-fetch on re-clicking an already-viewed history turn. Regression tests in ui/frontend/tests/turn-navigator.test.ts; ui/docs/navigation.md updated. FUNCTIONAL.md/ARCHITECTURE.md did not describe this micro-behavior → untouched (mirror FUNCTIONAL_ru.md also untouched).

Next: nothing — F8-02 done. Umbrella #43 (F8 manual-QA loop) remains owner-driven; further subtasks come as individual issues.

<!-- issue-agent:worklog --> <details> <summary>Working log (issue-agent) — click to expand</summary> **State:** done **Updated:** 2026-05-26T05:14Z **Branch / PR:** `feature/issue-45-turn-navigator-noop` → PR #57 MERGED into `development` at `1f6791549a25e014370744c44d0fcc896aeb76a0` **Merge gate passed (this run):** - PR mergeable, base `development`, body contains `Closes #45`. - CI green for head `e82c9f8b`: ui-test push (run 346) success, ui-test pull_request (run 347) success, dev-deploy (run 348) success. Combined commit-status carried the known phantom `pending` on the push context — workflow run conclusions are authoritative. - APPROVED review by issue author (owner, review id 6), `stale: false`, `commit_id == e82c9f8b…` (current head). - Zero PR-level comments, zero review-line comments — no threads to resolve. - Issue #45 was `open` at merge time — no cancel signal. **Post-merge:** `Closes #45` auto-closed the issue at 2026-05-26T05:13:24Z; set `claude/done` (the exclusive `claude/*` scope cleared `claude/in-review`). Owner's confirmation comment (335) acknowledged before merge. **Shipped:** guard `if (turn === gameState.viewedTurn) return;` in `ui/frontend/src/lib/header/turn-navigator.svelte::goToTurn` — re-clicking the on-screen turn closes the popover and stops. Same fix incidentally drops the redundant re-fetch on re-clicking an already-viewed history turn. Regression tests in `ui/frontend/tests/turn-navigator.test.ts`; `ui/docs/navigation.md` updated. `FUNCTIONAL.md`/`ARCHITECTURE.md` did not describe this micro-behavior → untouched (mirror `FUNCTIONAL_ru.md` also untouched). **Next:** nothing — F8-02 done. Umbrella #43 (F8 manual-QA loop) remains owner-driven; further subtasks come as individual issues. </details>
developer added
claude
in-review
and removed
claude
working
labels 2026-05-25 22:25:43 +00:00
Owner

@owner, готово — PR #57 ждёт твоего ревью.

Что было. Клик по строке текущего хода в навигаторе шёл через returnToCurrent()viewTurn(currentTurn), а тот всегда дёргал бэкенд (fetchGameReport, мимо кэша) и прогонял вид через loading (перерисовка). На ходе 0 единственная строка списка — это и есть живой ход, поэтому открыть список и кликнуть по нему = гарантированный лишний запрос и перерисовка того же снимка.

Что сделала. В goToTurn (turn-navigator.svelte) добавила охранник: if (turn === gameState.viewedTurn) return; — повторный выбор хода, который уже на экране, просто закрывает поповер, и всё. Условие написала через viewedTurn, а не как спец-случай «ход 0»: заодно ушёл такой же лишний повторный запрос при повторном клике по уже открытому историческому ходу. Выход из истории работает как прежде — там просматриваемый ход отличается от целевого, так что returnToCurrent() / viewTurn(N) отрабатывают.

Файлы.

  • ui/frontend/src/lib/header/turn-navigator.svelte — фикс + комментарий в шапке.
  • ui/frontend/tests/turn-navigator.test.ts — 2 регрессионных теста (no-op на ходе 0 с закрытием поповера; no-op при повторном выборе уже открытого исторического хода).
  • ui/docs/navigation.md — описание no-op.

FUNCTIONAL.md / ARCHITECTURE.md этот микро-no-op не описывают, так что их (и FUNCTIONAL_ru.md) не трогала.

Тесты. Локально весь Vitest зелёный (79 файлов / 776 тестов), svelte-check — 0 ошибок / 0 предупреждений. CI ui-test (push + PR) — зелёный; интеграционный набор не запускается (его пути не включают ui/frontend).

Мелочь: в сводном commit-status у контекста push может висеть фантомный pending — это та самая известная причуда Gitea, оба прогона по факту success.

Мерджить не буду — жду твой APPROVED, тогда вмерджу через merge-gate.

@owner, готово — PR #57 ждёт твоего ревью. **Что было.** Клик по строке текущего хода в навигаторе шёл через `returnToCurrent()` → `viewTurn(currentTurn)`, а тот всегда дёргал бэкенд (`fetchGameReport`, мимо кэша) и прогонял вид через `loading` (перерисовка). На ходе 0 единственная строка списка — это и есть живой ход, поэтому открыть список и кликнуть по нему = гарантированный лишний запрос и перерисовка того же снимка. **Что сделала.** В `goToTurn` (`turn-navigator.svelte`) добавила охранник: `if (turn === gameState.viewedTurn) return;` — повторный выбор хода, который уже на экране, просто закрывает поповер, и всё. Условие написала через `viewedTurn`, а не как спец-случай «ход 0»: заодно ушёл такой же лишний повторный запрос при повторном клике по уже открытому *историческому* ходу. Выход из истории работает как прежде — там просматриваемый ход отличается от целевого, так что `returnToCurrent()` / `viewTurn(N)` отрабатывают. **Файлы.** - `ui/frontend/src/lib/header/turn-navigator.svelte` — фикс + комментарий в шапке. - `ui/frontend/tests/turn-navigator.test.ts` — 2 регрессионных теста (no-op на ходе 0 с закрытием поповера; no-op при повторном выборе уже открытого исторического хода). - `ui/docs/navigation.md` — описание no-op. `FUNCTIONAL.md` / `ARCHITECTURE.md` этот микро-no-op не описывают, так что их (и `FUNCTIONAL_ru.md`) не трогала. **Тесты.** Локально весь Vitest зелёный (79 файлов / 776 тестов), `svelte-check` — 0 ошибок / 0 предупреждений. CI `ui-test` (push + PR) — зелёный; интеграционный набор не запускается (его пути не включают `ui/frontend`). _Мелочь:_ в сводном commit-status у контекста `push` может висеть фантомный `pending` — это та самая известная причуда Gitea, оба прогона по факту `success`. Мерджить не буду — жду твой `APPROVED`, тогда вмерджу через merge-gate.
Owner

@owner, да, увидела твой комментарий — и это ровно то, что уже в PR #57, я не завязывалась на «ход 0».

Условие в goToTurnif (turn === gameState.viewedTurn) return;, где viewedTurn это и есть ход, который сейчас выбран/показан в игровом UI (та самая подсвеченная строка списка). То есть no-op срабатывает для любого хода, который выбран, а не только для нулевого. Ход 0 — просто самый заметный случай: там выбранный ход всегда совпадает с текущим, поэтому баг и был виден всегда.

Поведение по случаям:

  • живой ход N, клик по строке N (она выбрана) → no-op;
  • смотрю историю (ход 2), клик по ходу 2 (выбран) → no-op;
  • смотрю историю (ход 2), клик по живому ходу 5 (он НЕ выбран) → выходим из истории, реальная работа.

Один нюанс на всякий случай: я трактовала «текущий» как «выбранный в UI» (viewedTurn) — именно из твоего «то есть выбран в игровом UI». Если под «текущим» ты имел в виду строго живой ход сервера (currentTurn), а не выбранный, то отличие лишь в одном случае — повторный клик по уже открытому историческому ходу: сейчас это тоже no-op (что, по-моему, правильно — это тот же лишний запрос). Скажи, если хочешь сузить до строго живого хода, поправлю.

@owner, да, увидела твой комментарий — и это ровно то, что уже в PR #57, я не завязывалась на «ход 0». Условие в `goToTurn` — `if (turn === gameState.viewedTurn) return;`, где `viewedTurn` это и есть ход, который сейчас выбран/показан в игровом UI (та самая подсвеченная строка списка). То есть no-op срабатывает для **любого** хода, который выбран, а не только для нулевого. Ход 0 — просто самый заметный случай: там выбранный ход всегда совпадает с текущим, поэтому баг и был виден всегда. Поведение по случаям: - живой ход N, клик по строке N (она выбрана) → no-op; - смотрю историю (ход 2), клик по ходу 2 (выбран) → no-op; - смотрю историю (ход 2), клик по живому ходу 5 (он НЕ выбран) → выходим из истории, реальная работа. Один нюанс на всякий случай: я трактовала «текущий» как «выбранный в UI» (`viewedTurn`) — именно из твоего «то есть выбран в игровом UI». Если под «текущим» ты имел в виду строго живой ход сервера (`currentTurn`), а не выбранный, то отличие лишь в одном случае — повторный клик по уже открытому историческому ходу: сейчас это тоже no-op (что, по-моему, правильно — это тот же лишний запрос). Скажи, если хочешь сузить до строго живого хода, поправлю.
Author
Collaborator

Всё отлично, проверил. Твоё чутьё тебя не подвело. :) Постановка размытая - реализация превосходная, спасибо 👍

Всё отлично, проверил. Твоё чутьё тебя не подвело. :) Постановка размытая - реализация превосходная, спасибо 👍
developer added
claude
done
and removed
claude
in-review
labels 2026-05-26 05:13:32 +00:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: developer/galaxy-game#45