[F8-06] Калькулятор: шаги, замочки, пол tech, баг speed-lock #49

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

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

Цель: Калькулятор: корректные шаги числовых инпутов, унификация замочков, нижняя граница по текущему tech, фикс бага speed-lock.

Пункты из #43:

9. Калькулятор. В числовых инпутах, относящихся к ship class (drive, weapons, shields, cargo) нажатие на стрелочку вверх (увеличение значения на 0.01) работает слишком буквально: в ячейке становится значние 0 -> 0.01 что не является валидным. Предлагаю от 0 вверх переходить сразу на 1, потом шаг +0.1. Аналогично, вниз: шаг -0.1, когда дошли до 1.0 следующее нажатие вниз сбрасывает на ноль.
10. Калькулятор. "Пляшут" замочки при ручном вводе tech-уровней для класса корабля. Давай оставим справа от полей ввода всегда зарезервированное место под эти замочки, чтобы их пропада-появление не влияла на ширину полей tech. То же самое с полем ввода MAT планеты. Вообще, предлагаю для уменьшения шума и унификации некоторой логики, сделать tech-замочки и MAT-замочек в такой же логике, как и lock-замочки в секции ниже: по умолчанию отображается число и рядом открытый замок. Когда пользователь нажимает на замок - он становится закрытым и вместо числа появляется input для возможности ввода своего значения.
11. Калькулятор. Поля для уровней tech не должны быть меньше текущего уровня технологий игрока на данном ходе.
12. Калькулятор. Задаю параметры корабля D=1 W=0 A=0 S=0 C=0, скорость у него считается 20. Но когда я нажимаю на замочек напротив "speed" - появляется инпут со значением 20 и красной рамкой с ошибкой "this target cannot be reached within the current design", это явный баг UI.

Заметка. п.9 и п.12 — баги; п.10 — зарезервированное место под замочки + единый идиом «число + замок → input» (как lock-замочки секцией ниже), включая MAT планеты; п.11 — нижняя граница уровней tech = текущий уровень технологий игрока на этом ходе.


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

Подзадача полировки UI (этап **F8**), родительский #43. **Цель:** Калькулятор: корректные шаги числовых инпутов, унификация замочков, нижняя граница по текущему tech, фикс бага speed-lock. **Пункты из #43:** > **9.** Калькулятор. В числовых инпутах, относящихся к ship class (drive, weapons, shields, cargo) нажатие на стрелочку вверх (увеличение значения на 0.01) работает слишком буквально: в ячейке становится значние 0 -> 0.01 что не является валидным. Предлагаю от 0 вверх переходить сразу на 1, потом шаг +0.1. Аналогично, вниз: шаг -0.1, когда дошли до 1.0 следующее нажатие вниз сбрасывает на ноль. > **10.** Калькулятор. "Пляшут" замочки при ручном вводе tech-уровней для класса корабля. Давай оставим справа от полей ввода всегда зарезервированное место под эти замочки, чтобы их пропада-появление не влияла на ширину полей tech. То же самое с полем ввода MAT планеты. Вообще, предлагаю для уменьшения шума и унификации некоторой логики, сделать tech-замочки и MAT-замочек в такой же логике, как и lock-замочки в секции ниже: по умолчанию отображается число и рядом открытый замок. Когда пользователь нажимает на замок - он становится закрытым и вместо числа появляется input для возможности ввода своего значения. > **11.** Калькулятор. Поля для уровней tech не должны быть меньше текущего уровня технологий игрока на данном ходе. > **12.** Калькулятор. Задаю параметры корабля D=1 W=0 A=0 S=0 C=0, скорость у него считается 20. Но когда я нажимаю на замочек напротив "speed" - появляется инпут со значением 20 и красной рамкой с ошибкой "this target cannot be reached within the current design", это явный баг UI. _Заметка._ п.9 и п.12 — баги; п.10 — зарезервированное место под замочки + единый идиом «число + замок → input» (как lock-замочки секцией ниже), включая MAT планеты; п.11 — нижняя граница уровней tech = текущий уровень технологий игрока на этом ходе. --- _Порядок обработки: **F8-06** из 12. Создано в рамках #43; зонтичный issue остаётся открытым до закрытия всех подзадач._
owner added the Kind/Bug
Priority
Medium
3
Kind/Enhancementready
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-26 07:01:44 +00:00
developer added ready and removed
claude
working
labels 2026-05-26 07:09:00 +00:00
developer added
claude
working
and removed ready labels 2026-05-26 10:25:24 +00:00
developer added ready and removed
claude
working
labels 2026-05-26 10:27:09 +00:00
developer added
claude
working
and removed ready labels 2026-05-26 12:12:09 +00:00
Owner
Working log (issue-agent) — click to expand

State: done
Updated: 2026-05-26T17:24Z
Branch / PR: PR #61 merged (merge commit b03993f) · feature branch auto-deleted
Confirmed:

  • Owner submitted APPROVED review #13 on head b01a60e (stale=false, comments_count=0) at 17:20Z.
  • All three PR-context workflow runs on b01a60e are conclusion=success (395 go-unit, 396 integration, 397 ui-test). The combined commit-status reads failure only because of run 394 (ui-test/push) — auto-cancelled when the matching ui-test/pull_request run started; this is the documented phantom-failure pattern.
  • No open discussion threads on the PR (issues/61/comments empty; only review is the APPROVED one).
  • PR was mergeable=true; merge gate cleared on every criterion.
    Open question:
    Decisions:
  • Merged via standard merge commit (default_merge_style: merge); feature branch deleted via delete_branch_after_merge: true.
  • Issue auto-closed on merge via Closes #49; terminal label flipped working → done through the exclusive claude/* scope.
    Next:
<!-- issue-agent:worklog --> <details> <summary>Working log (issue-agent) — click to expand</summary> **State:** done **Updated:** 2026-05-26T17:24Z **Branch / PR:** PR #61 merged (merge commit b03993f) · feature branch auto-deleted **Confirmed:** - Owner submitted APPROVED review #13 on head b01a60e (stale=false, comments_count=0) at 17:20Z. - All three PR-context workflow runs on b01a60e are conclusion=success (395 go-unit, 396 integration, 397 ui-test). The combined commit-status reads `failure` only because of run 394 (ui-test/push) — auto-cancelled when the matching ui-test/pull_request run started; this is the documented phantom-failure pattern. - No open discussion threads on the PR (issues/61/comments empty; only review is the APPROVED one). - PR was mergeable=true; merge gate cleared on every criterion. **Open question:** — **Decisions:** - Merged via standard merge commit (`default_merge_style: merge`); feature branch deleted via `delete_branch_after_merge: true`. - Issue auto-closed on merge via `Closes #49`; terminal label flipped working → done through the exclusive `claude/*` scope. **Next:** — </details>
developer added
claude
in-review
and removed
claude
working
labels 2026-05-26 12:38:02 +00:00
Owner

@owner — готово к ревью: PR #61 (feature/issue-49-calculator-polishdevelopment). Все четыре пункта одной правкой; CI зелёный (go-unit, ui-test, integration).

Коротко по пунктам:

  • п.9 — умный шаг ship-block инпутов (drive/weapons/shields/cargo). ArrowUp/ArrowDown теперь обрабатываются JS-обработчиком: с 0 прыжок сразу на 1 (минуя невалидную зону (0, 1)), дальше шаг ±0.1; ArrowDown на 1 схлопывает на 0. Нативный спиннер на этих инпутах спрятан (он бы воспроизвёл проблему с 0.01). Armament оставлен с нативным шагом 1.
  • п.10 — единый идиом замочка + зарезервированное место. Tech-замочки и MAT-замочек переведены на тот же идиом, что и lock-замочки секцией ниже: по умолчанию открытый замок 🔓 рядом с числом, по клику открывается input с закрытым замком 🔒. Слот под замок зарезервирован, ширина колонки больше не «пляшет». Для tech ввод дополнительно автофокусится после клика по 🔓.
  • п.11 — нижняя граница tech. Tech-инпуты в design-area и target tech в модернизации теперь не пускают ниже текущего уровня технологий игрока на этом ходу — красная рамка + tooltip.
  • п.12 — баг speed-lock. Исправлено в pkg/calc/solve.go DriveForSpeed: при restMass == 0 (корабль D=1, остальные 0) достижимая скорость ровно одна — потолок 20 × driveTech, поэтому solver больше не помечает её как недостижимую. Fake-core зеркало обновлено, добавлены параллельные unit-тесты.

Если в каком-то месте моя интерпретация разошлась с задумкой — скажи, поправлю. По умолчанию мерж пойдёт через merge-gate после твоего APPROVED-ревью на текущий head.

@owner — готово к ревью: **PR #61** (`feature/issue-49-calculator-polish` → `development`). Все четыре пункта одной правкой; CI зелёный (`go-unit`, `ui-test`, `integration`). Коротко по пунктам: - **п.9 — умный шаг ship-block инпутов (drive/weapons/shields/cargo).** ArrowUp/ArrowDown теперь обрабатываются JS-обработчиком: с 0 прыжок сразу на 1 (минуя невалидную зону `(0, 1)`), дальше шаг ±0.1; ArrowDown на 1 схлопывает на 0. Нативный спиннер на этих инпутах спрятан (он бы воспроизвёл проблему с 0.01). Armament оставлен с нативным шагом 1. - **п.10 — единый идиом замочка + зарезервированное место.** Tech-замочки и MAT-замочек переведены на тот же идиом, что и lock-замочки секцией ниже: по умолчанию открытый замок 🔓 рядом с числом, по клику открывается input с закрытым замком 🔒. Слот под замок зарезервирован, ширина колонки больше не «пляшет». Для tech ввод дополнительно автофокусится после клика по 🔓. - **п.11 — нижняя граница tech.** Tech-инпуты в design-area и target tech в модернизации теперь не пускают ниже текущего уровня технологий игрока на этом ходу — красная рамка + tooltip. - **п.12 — баг speed-lock.** Исправлено в `pkg/calc/solve.go` `DriveForSpeed`: при `restMass == 0` (корабль D=1, остальные 0) достижимая скорость ровно одна — потолок `20 × driveTech`, поэтому solver больше не помечает её как недостижимую. Fake-core зеркало обновлено, добавлены параллельные unit-тесты. Если в каком-то месте моя интерпретация разошлась с задумкой — скажи, поправлю. По умолчанию мерж пойдёт через merge-gate после твоего APPROVED-ревью на текущий head.
Author
Collaborator

Спасибо! Мелкие шероховатости:

  • п.9 - а нельзя было нативный спиннер "починить" каким-нибудь обработчиком/перехватчиком? Сейчас странно стало. Надо либо попробовать обработать все спиннеры, либо у armament его тоже убрать.
  • п. 10 - давай tech-значения, которые сейчас идут простым текстом (не инпутом) отображать как в отчёте, с 3 знаками после запятой. Вообще, если подумать, очень поможет, если все такие значения, которые идут обычным label, будут в таком же формате и fixed-шрифтом и выравнивание по правому краю.
  • п.12 - та же проблема с mass / attack / defense, при прокручивания спиннера вниз они уводят параметры корабля ниже единицы в некоторых случаях - проверь все lockable-инпуты на нормальное поведение, пожалуйста.
  • Выбор имеющегося корабля при клике в поле "new class name" работает неочевидно. После клика на элемент в выпадающем списке сначала ничего не меняется в параметрах калькулятора, а потом, когда дополнительным кликом я увожу фокус из этого поля, данные корабля загружаются в калькулятор. Надо бы ловить выбор из списка сразу, но лучше превентивно сделать вот что: если пользователь менял вручную параметры корабля и они сейчас не совпадают с ранее загруженным кораблем (или дефолтным состоянием калькулятора), то при клике в выпадающем списке надо показать уведомление с вопросом вроде такого: "сбросить изменения?" да/нет. Если нет - тогда не подгружаем ничего из выпадающего списка.
Спасибо! Мелкие шероховатости: - п.9 - а нельзя было нативный спиннер "починить" каким-нибудь обработчиком/перехватчиком? Сейчас странно стало. Надо либо попробовать обработать все спиннеры, либо у armament его тоже убрать. - п. 10 - давай tech-значения, которые сейчас идут простым текстом (не инпутом) отображать как в отчёте, с 3 знаками после запятой. Вообще, если подумать, очень поможет, если все такие значения, которые идут обычным label, будут в таком же формате и fixed-шрифтом и выравнивание по правому краю. - п.12 - та же проблема с mass / attack / defense, при прокручивания спиннера вниз они уводят параметры корабля ниже единицы в некоторых случаях - проверь все lockable-инпуты на нормальное поведение, пожалуйста. - Выбор имеющегося корабля при клике в поле "new class name" работает неочевидно. После клика на элемент в выпадающем списке сначала ничего не меняется в параметрах калькулятора, а потом, когда дополнительным кликом я увожу фокус из этого поля, данные корабля загружаются в калькулятор. Надо бы ловить выбор из списка сразу, но лучше превентивно сделать вот что: если пользователь менял вручную параметры корабля и они сейчас не совпадают с ранее загруженным кораблем (или дефолтным состоянием калькулятора), то при клике в выпадающем списке надо показать уведомление с вопросом вроде такого: "сбросить изменения?" да/нет. Если нет - тогда не подгружаем ничего из выпадающего списка.
Owner

@owner — поправил все четыре пункта, новый head cbf7f65 в PR #61.

  • п.9. Выбрал второй из твоих вариантов и расширил его: натив-спиннер теперь спрятан на ВСЕХ числовых инпутах калькулятора (DWSC + armament + tech + MAT + custom load + lock + target tech), стрелочки вверх/вниз — единственный affordance для шага. Колонки больше не «прыгают», калькулятор читается одинаково сверху донизу. Для armament стрелочки шагают ±1 (с клампом на 0), для tech/lock — ±0.001, для MAT/load — ±0.01. Умный «0 ↔ 1» прыжок на ship-блоках сохранён. Принцип «вмешиваться в нативный спиннер» отверг сознательно: события клика по up/down кнопкам напрямую не ловятся, а отличать «пользователь нажал стрелку» от «пользователь ввёл 0.5» через inputType — ненадёжная эвристика, ломается между браузерами; общий путь через ArrowUp/Down оказался и проще, и предсказуемее.
  • п.10. Tech-лейблы и MAT-лейбл теперь читаются через тот же Ceil3-форматтер, что и результаты в отчёте: 3 знака после запятой, tabular-nums, выравнивание по правому краю — формат и шрифтовая ширина те же, что в derived results. То же касается read-only клетки goal-seek (когда блок back-solved). Если под «fixed-шрифтом» ты имел в виду именно монопространственный font-family, а не tabular-nums как в отчёте — скажи, переведу на monospace.
  • п.12. computeCalculator теперь валидирует back-solved блок против того же правила DWSC (0 или ≥ 1), что и обычный ввод. Если solver попадает в (0, 1) — например attack 0.5 при weaponsTech 1.5 = weapons 0.333… — lock помечается infeasible (красная рамка + тултип), а в read-only клетке остаётся то, что ввёл пользователь руками. Силуэт корабля больше не уезжает молча ниже единицы при прокрутке спиннера. Сама прокрутка теперь идёт стрелочками с шагом 0.001 (см. п.9), так что сжать в (0, 1) случайным колесом мыши тоже сложнее.
  • новое (выбор корабля из выпадающего списка). Перевёл загрузку с change на input с проверкой InputEvent.inputType: datalist-replacement даёт "insertReplacementText" в Chromium/WebKit и undefined в Firefox, обычная печатка несёт "insertText"/"deleteContent…". То есть клик по опции грузит класс сразу, без второго клика. Перед загрузкой сравниваю текущие блоки с ранее загруженным классом (или с дефолтными нулями, если ничего не было загружено); если есть ручные изменения — спрашиваю Сбросить несохранённые изменения и загрузить класс «…»? через нативный window.confirm (отдельной модалки у нас в калькуляторе нет, native-confirm — минимальный шаг). При «нет» возвращаю имя в поле к предыдущему загруженному (или к пустому) и оставляю design нетронутым.

Покрыто шестью новыми кейсами в calculator-tab.test.ts и calc-model.test.ts (Arrow-step для armament, форматтер на tech-/MAT-лейблах, infeasible-lock на attack→weapons и emptyMass→cargo, ArrowKey-шаг на lock-инпуте, иммедиат-загрузка из datalist + confirm-блокирует + confirm-пропускает). Все 779 vitest зелёные, go test ./pkg/calc/... зелёный, svelte-check чист. Жду твоего ревью на новом head; мерж пойдёт через merge-gate после APPROVED.

@owner — поправил все четыре пункта, новый head **cbf7f65** в **PR #61**. - **п.9.** Выбрал второй из твоих вариантов и расширил его: натив-спиннер теперь спрятан на ВСЕХ числовых инпутах калькулятора (DWSC + armament + tech + MAT + custom load + lock + target tech), стрелочки вверх/вниз — единственный affordance для шага. Колонки больше не «прыгают», калькулятор читается одинаково сверху донизу. Для armament стрелочки шагают ±1 (с клампом на 0), для tech/lock — ±0.001, для MAT/load — ±0.01. Умный «0 ↔ 1» прыжок на ship-блоках сохранён. Принцип «вмешиваться в нативный спиннер» отверг сознательно: события клика по up/down кнопкам напрямую не ловятся, а отличать «пользователь нажал стрелку» от «пользователь ввёл 0.5» через inputType — ненадёжная эвристика, ломается между браузерами; общий путь через ArrowUp/Down оказался и проще, и предсказуемее. - **п.10.** Tech-лейблы и MAT-лейбл теперь читаются через тот же `Ceil3`-форматтер, что и результаты в отчёте: 3 знака после запятой, tabular-nums, выравнивание по правому краю — формат и шрифтовая ширина те же, что в derived results. То же касается read-only клетки goal-seek (когда блок back-solved). Если под «fixed-шрифтом» ты имел в виду именно монопространственный font-family, а не tabular-nums как в отчёте — скажи, переведу на `monospace`. - **п.12.** `computeCalculator` теперь валидирует back-solved блок против того же правила DWSC (`0` или `≥ 1`), что и обычный ввод. Если solver попадает в (0, 1) — например attack 0.5 при weaponsTech 1.5 = weapons 0.333… — lock помечается infeasible (красная рамка + тултип), а в read-only клетке остаётся то, что ввёл пользователь руками. Силуэт корабля больше не уезжает молча ниже единицы при прокрутке спиннера. Сама прокрутка теперь идёт стрелочками с шагом 0.001 (см. п.9), так что сжать в (0, 1) случайным колесом мыши тоже сложнее. - **новое (выбор корабля из выпадающего списка).** Перевёл загрузку с `change` на `input` с проверкой `InputEvent.inputType`: datalist-replacement даёт `"insertReplacementText"` в Chromium/WebKit и `undefined` в Firefox, обычная печатка несёт `"insertText"`/`"deleteContent…"`. То есть клик по опции грузит класс сразу, без второго клика. Перед загрузкой сравниваю текущие блоки с ранее загруженным классом (или с дефолтными нулями, если ничего не было загружено); если есть ручные изменения — спрашиваю `Сбросить несохранённые изменения и загрузить класс «…»?` через нативный `window.confirm` (отдельной модалки у нас в калькуляторе нет, native-confirm — минимальный шаг). При «нет» возвращаю имя в поле к предыдущему загруженному (или к пустому) и оставляю design нетронутым. Покрыто шестью новыми кейсами в `calculator-tab.test.ts` и `calc-model.test.ts` (Arrow-step для armament, форматтер на tech-/MAT-лейблах, infeasible-lock на attack→weapons и emptyMass→cargo, ArrowKey-шаг на lock-инпуте, иммедиат-загрузка из datalist + confirm-блокирует + confirm-пропускает). Все 779 vitest зелёные, `go test ./pkg/calc/...` зелёный, `svelte-check` чист. Жду твоего ревью на новом head; мерж пойдёт через merge-gate после APPROVED.
Author
Collaborator

Всё ещё остались некоторые "проблемки".

  • п. 10, значения tech-уровней, mass, speed, attack, defense, bombing, cargo capacity, MAT - в режиме, когда пользователь их НЕ редактирует, отображаются всё ещё НЕ с трёмя знаками после десятичной запятой (или точки, если ты американец). Пример: сейчас отображается "1", надо "1.000" и т.п. Исправь пожалуйста. Округление сделай обычное, арифметическое, в большую сторону. Да, шрифт для значений хотелось бы monospace с выравниванием по правому краю.
  • Дополнительно: в инпутах так же не давать пользователю вводить больше трёх знаков после запятой, иначе UX становится ужасным. Тут нюанс: когда пользователь ставит на lock какое-то значение, то вычисляемые параметры корабля могут оказаться точнее, чем три знака после запятой - их надо так же округлять до трёх в большую сторону.

Если описанная выше логика не ложится на код - приходи обсуждать, приноси предложения.

По остальным пунктам посмотрел - всё в норме, спасибо!

Всё ещё остались некоторые "проблемки". - п. 10, значения tech-уровней, mass, speed, attack, defense, bombing, cargo capacity, MAT - в режиме, когда пользователь их НЕ редактирует, отображаются всё ещё НЕ с трёмя знаками после десятичной запятой (или точки, если ты американец). Пример: сейчас отображается "1", надо "1.000" и т.п. Исправь пожалуйста. Округление сделай обычное, арифметическое, в большую сторону. Да, шрифт для значений хотелось бы monospace с выравниванием по правому краю. - Дополнительно: в инпутах так же не давать пользователю вводить больше трёх знаков после запятой, иначе UX становится ужасным. Тут нюанс: когда пользователь ставит на lock какое-то значение, то вычисляемые параметры корабля могут оказаться точнее, чем три знака после запятой - их надо так же округлять до трёх в большую сторону. Если описанная выше логика не ложится на код - приходи обсуждать, приноси предложения. По остальным пунктам посмотрел - всё в норме, спасибо!
Owner

@owner — поправил всё из последнего комментария, новый head cc4727a в PR #61. CI зелёный по всем трём workflows (go-unit, ui-test, integration).

  • п.10 (продолжение) — 3 знака после запятой ВСЕГДА. Это была дырка в прошлой правке: fmt округлял ceil-ом до 3 знаков, но печатал через maximumFractionDigits: 3, поэтому целые значения шли как "1". Теперь и min, и max = 3, и useGrouping: false. Это разом подтянуло все лейблы, которые ты перечислил: tech, mass, speed, attack, defence, bombing, cargo capacity, MAT, ships per turn, modernization cost, full capacity, read-only клетка goal-seek блока. 2020.000, 11.000, 1.21.200. Группировку тысяч убрал, потому что та же строка теперь embed-ится в <input type="number"> (read-only клетка back-solved блока) и "1,234.000" туда не парсится.
  • monospace + правый край. Подключил существующий токен --font-mono (тот же стек, что в reportui-monospace, SF Mono, Cascadia Code, Menlo, Consolas, monospace) ко всем числовым лейблам и инпутам калькулятора: .cell .val, .cell input, .tech-val, .mat-val, .full-capacity, .custom-load, .planet-stats dd, плюс блок ship-design-area. tabular-nums + text-align: right сохранены, поэтому колонки выстраиваются строго в столбик.
  • п.новое — кап на 3 знака в инпутах. Добавил один общий хелпер capDecimals(event, apply): на input-событии, если в текстовом значении больше трёх знаков после точки — отрезает четвёртый+ символ и явно перезаписывает связанное состояние через apply. Явная перезапись важна, потому что у Svelte bind:value свой обработчик input, и он уже прочитал «перепрецизионное» число до нас; без apply следующий реактивный флэш вернул бы длинную строку обратно в DOM. Применил ко всем числовым инпутам калькулятора: DWSC-блоки, tech, MAT, custom load, lock value, target tech модернизации.
  • «вычисляемые параметры корабля». Тут отдельной правки в state не понадобилось — resolvedCeil уже прогоняет back-solved блок через core.ceil3, и fmt повторно ceil-ит при выводе (идемпотентно), так что после смены формата лейбла back-solved клетка тоже стабильно показывает 3 знака. Сам внутренний числовой стейт оставил «как пришёл от солвера» — лгать про точность в инпуте не хочется, а отображение уже корректное.

Покрыто пятью новыми тестами в calculator-tab.test.ts: 3-decimal padding на tech-лейбле, на MAT-лейбле и на derived результате (целое empty mass), плюс кап на каждом классе инпутов (MAT / custom-load, tech + target tech, lock value, ship-block). Все 32 кейса в файле зелёные, общий vitest набор — 784 passed / 16 skipped (3 wasm-core теста требуют make wasm локально и проходят в CI). pnpm run check чист.

Если формат / шрифт где-то ещё надо подтянуть — скажи, поправлю. По умолчанию мерж пойдёт через merge-gate после твоего APPROVED-ревью на cc4727a.

@owner — поправил всё из последнего комментария, новый head **cc4727a** в **PR #61**. CI зелёный по всем трём workflows (`go-unit`, `ui-test`, `integration`). - **п.10 (продолжение) — 3 знака после запятой ВСЕГДА.** Это была дырка в прошлой правке: `fmt` округлял ceil-ом до 3 знаков, но печатал через `maximumFractionDigits: 3`, поэтому целые значения шли как `"1"`. Теперь и `min`, и `max` = 3, и `useGrouping: false`. Это разом подтянуло все лейблы, которые ты перечислил: tech, mass, speed, attack, defence, bombing, cargo capacity, MAT, ships per turn, modernization cost, full capacity, read-only клетка goal-seek блока. `20` → `20.000`, `1` → `1.000`, `1.2` → `1.200`. Группировку тысяч убрал, потому что та же строка теперь embed-ится в `<input type="number">` (read-only клетка back-solved блока) и `"1,234.000"` туда не парсится. - **monospace + правый край.** Подключил существующий токен `--font-mono` (тот же стек, что в `report` — `ui-monospace, SF Mono, Cascadia Code, Menlo, Consolas, monospace`) ко всем числовым лейблам и инпутам калькулятора: `.cell .val`, `.cell input`, `.tech-val`, `.mat-val`, `.full-capacity`, `.custom-load`, `.planet-stats dd`, плюс блок ship-design-area. `tabular-nums` + `text-align: right` сохранены, поэтому колонки выстраиваются строго в столбик. - **п.новое — кап на 3 знака в инпутах.** Добавил один общий хелпер `capDecimals(event, apply)`: на `input`-событии, если в текстовом значении больше трёх знаков после точки — отрезает четвёртый+ символ и явно перезаписывает связанное состояние через `apply`. Явная перезапись важна, потому что у Svelte `bind:value` свой обработчик `input`, и он уже прочитал «перепрецизионное» число до нас; без `apply` следующий реактивный флэш вернул бы длинную строку обратно в DOM. Применил ко всем числовым инпутам калькулятора: DWSC-блоки, tech, MAT, custom load, lock value, target tech модернизации. - **«вычисляемые параметры корабля».** Тут отдельной правки в state не понадобилось — `resolvedCeil` уже прогоняет back-solved блок через `core.ceil3`, и `fmt` повторно ceil-ит при выводе (идемпотентно), так что после смены формата лейбла back-solved клетка тоже стабильно показывает 3 знака. Сам внутренний числовой стейт оставил «как пришёл от солвера» — лгать про точность в инпуте не хочется, а отображение уже корректное. Покрыто пятью новыми тестами в `calculator-tab.test.ts`: 3-decimal padding на tech-лейбле, на MAT-лейбле и на derived результате (целое empty mass), плюс кап на каждом классе инпутов (MAT / custom-load, tech + target tech, lock value, ship-block). Все 32 кейса в файле зелёные, общий vitest набор — 784 passed / 16 skipped (3 wasm-core теста требуют `make wasm` локально и проходят в CI). `pnpm run check` чист. Если формат / шрифт где-то ещё надо подтянуть — скажи, поправлю. По умолчанию мерж пойдёт через merge-gate после твоего APPROVED-ревью на cc4727a.
Author
Collaborator

Выглядит очень классно, спасибо! Парочка финальных мелких моментов:

  1. при выборе корабля из уже имеющихся, появляется кнопка "delete <ship_class_name>" - давай её уберём отсюда совсем, функционал не калькулятора, а реализация будет подправлена в #53.
  2. Значения "bombing" и "cargo capacity" выровнять по вертикали под значения mass/speed/attack/defense, сейчас они смещены вправо из-за того что у них нет "замочка" и это смотрится не очень.
Выглядит очень классно, спасибо! Парочка финальных мелких моментов: 1. при выборе корабля из уже имеющихся, появляется кнопка "delete <ship_class_name>" - давай её уберём отсюда совсем, функционал не калькулятора, а реализация будет подправлена в #53. 2. Значения "bombing" и "cargo capacity" выровнять по вертикали под значения mass/speed/attack/defense, сейчас они смещены вправо из-за того что у них нет "замочка" и это смотрится не очень.
developer added
claude
working
and removed
claude
in-review
labels 2026-05-26 17:02:38 +00:00
Owner

@owner — поправил оба пункта, новый head b01a60e в PR #61. CI зелёный по всем трём workflows (go-unit, ui-test, integration).

  • п.1 — кнопка delete <ship_class_name> ушла из калькулятора. Снёс её разом с обвязкой: canDelete-derived, deleteClass-функцию, CSS-правило .delete, i18n-ключ game.calculator.action.delete (он нигде больше не использовался — у других удалений свои namespace'ы). Сам removeShipClass-флоу остался жив в lib/active-view/table-ship-classes.svelte (и у дизайнера); калькулятор просто перестал быть его второй точкой входа. Под #53 ты, как договаривались, перепилишь его уже там.
  • п.2 — bombing и cargo capacity выровнены под mass/speed/attack/defense. Причина дрейфа была в .cell { justify-content: flex-end }: в локабельных строках справа стоит кнопка-замочек, и значение прижимается к ней, а у bombing / cargo capacity замочка нет — значение упиралось прямо в правый край ячейки, на lock-width + gap правее. Положил в эти две ячейки скрытый плейсхолдер <span class="lock-slot" aria-hidden="true">🔓</span> со flex: none; font-size: 0.7rem; line-height: 1; visibility: hidden. Та же ширина, что у видимой кнопки-замочка, не в табстопе, не озвучивается скринридерами. Колонка теперь строго в столбик от mass до cargo capacity.

Документация: в ui/docs/calculator-ux.md секцию Create / load / delete переименовал в Create / load, оставил указатель, что delete-class живёт в ship-classes-таблице, и добавил строку про зарезервированный lock-slot.

Покрыто двумя новыми vitest-кейсами в calculator-tab.test.ts: после загрузки класса queryByTestId("calculator-delete") возвращает null; в ячейках bombing и cargo capacity присутствует .lock-slot. Все 34 кейса калькулятора зелёные, общий pnpm test — 786 passed / 16 skipped (3 wasm-core теста требуют make wasm локально и проходят в CI). pnpm run check чист.

Мерж по-прежнему пойдёт через merge-gate после твоего APPROVED-ревью на b01a60e.

@owner — поправил оба пункта, новый head **b01a60e** в PR #61. CI зелёный по всем трём workflows (`go-unit`, `ui-test`, `integration`). - **п.1 — кнопка `delete <ship_class_name>` ушла из калькулятора.** Снёс её разом с обвязкой: `canDelete`-derived, `deleteClass`-функцию, CSS-правило `.delete`, i18n-ключ `game.calculator.action.delete` (он нигде больше не использовался — у других удалений свои namespace'ы). Сам `removeShipClass`-флоу остался жив в `lib/active-view/table-ship-classes.svelte` (и у дизайнера); калькулятор просто перестал быть его второй точкой входа. Под #53 ты, как договаривались, перепилишь его уже там. - **п.2 — bombing и cargo capacity выровнены под mass/speed/attack/defense.** Причина дрейфа была в `.cell { justify-content: flex-end }`: в локабельных строках справа стоит кнопка-замочек, и значение прижимается к ней, а у bombing / cargo capacity замочка нет — значение упиралось прямо в правый край ячейки, на `lock-width + gap` правее. Положил в эти две ячейки скрытый плейсхолдер `<span class="lock-slot" aria-hidden="true">🔓</span>` со `flex: none; font-size: 0.7rem; line-height: 1; visibility: hidden`. Та же ширина, что у видимой кнопки-замочка, не в табстопе, не озвучивается скринридерами. Колонка теперь строго в столбик от mass до cargo capacity. Документация: в `ui/docs/calculator-ux.md` секцию `Create / load / delete` переименовал в `Create / load`, оставил указатель, что delete-class живёт в ship-classes-таблице, и добавил строку про зарезервированный lock-slot. Покрыто двумя новыми vitest-кейсами в `calculator-tab.test.ts`: после загрузки класса `queryByTestId("calculator-delete")` возвращает `null`; в ячейках bombing и cargo capacity присутствует `.lock-slot`. Все 34 кейса калькулятора зелёные, общий `pnpm test` — 786 passed / 16 skipped (3 wasm-core теста требуют `make wasm` локально и проходят в CI). `pnpm run check` чист. Мерж по-прежнему пойдёт через merge-gate после твоего APPROVED-ревью на b01a60e.
developer added
claude
in-review
and removed
claude
working
labels 2026-05-26 17:16:29 +00:00
developer added
claude
working
and removed
claude
in-review
labels 2026-05-26 17:23:17 +00:00
developer added
claude
done
and removed
claude
working
labels 2026-05-26 17:23:39 +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#49