mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-02 12:49:56 +00:00
@@ -0,0 +1,248 @@
|
||||
# Issue #203 — выключение названий скрывает все подписи комнат
|
||||
|
||||
- Дата: 2026-08-19
|
||||
- Тип: bug · приоритет P2 · ценность 7/10 · сложность 3/10
|
||||
- Issue: [#203](https://github.com/Matysh/houseplan-card/issues/203)
|
||||
- Ветка: `issue/203-hide-room-names`
|
||||
|
||||
Канонические документы: `docs/SCOPE.md`, `docs/UX-MODES.md`,
|
||||
`docs/STYLING-HOOKS.md`, `docs/USER-GUIDE.ru.md`, `docs/TESTING.md`.
|
||||
|
||||
## 1. Сценарий и персона
|
||||
|
||||
Администратор дома открывает настройки пространства, выключает «Отображать
|
||||
названия комнат (перетаскиваются)» и сохраняет. Он ожидает чистый View без
|
||||
постоянных подписей, например для маленького экрана, фонового чертежа с уже
|
||||
нанесёнными названиями или плана, где достаточно интерактивных устройств.
|
||||
|
||||
Это штатная часть J4/J6: явно выключенный визуальный слой должен исчезнуть на
|
||||
всех пользовательских представлениях одного пространства.
|
||||
|
||||
## 2. Что человек увидит до и после
|
||||
|
||||
**До:** draggable HTML-карточка исчезает вместе с температурой, влажностью,
|
||||
LQI и состоянием света, но на нарисованном плане без фонового изображения
|
||||
возникает другая SVG-подпись. Имя остаётся, перемещается в геометрический центр
|
||||
комнаты и меняет стиль. Компактная карточка пространства повторяет дефект.
|
||||
|
||||
**После:** при выключенной настройке в View, Devices editor и компактной
|
||||
карточке нет постоянной подписи комнаты ни в HTML, ни в SVG. В Plan editor имя
|
||||
по-прежнему временно показывается как редактируемый объект. При повторном
|
||||
включении возвращается прежняя draggable карточка с сохранённой позицией,
|
||||
масштабом, HA Area icon и разрешёнными метриками.
|
||||
|
||||
## 3. Подтверждённая проблема и причина
|
||||
|
||||
Persisted значение и основной resolver исправны:
|
||||
|
||||
- `spaceDisplayOf()` возвращает `showNames: false` для явного
|
||||
`settings.show_names: false`;
|
||||
- `_saveSpaceDialog()` записывает `show_names: d.showNames` для существующего
|
||||
пространства;
|
||||
- основной `.devlayer` перестаёт рендерить `_renderRoomLabel()`, поэтому
|
||||
HTML-карточка и её `.rlmetrics` действительно исчезают.
|
||||
|
||||
Ошибка находится в двух fallback-ветках. `_renderSvgRoomLabels()` полного
|
||||
renderer при `!space.bg && !disp.showNames` создаёт `<text class="rlabel">`.
|
||||
`renderSpaceCard()` независимо делает то же через `staticSvgLabels`. Они
|
||||
инвертируют смысл настройки. Скрытая изометрическая ветка дополнительно
|
||||
форсирует HTML-карточки при `iso && !space.bg`, даже если `showNames === false`.
|
||||
|
||||
Именно смена HTML-карточки на SVG-текст объясняет все детали репорта: имя
|
||||
остаётся, метрики пропадают, сохранённая layout-позиция не используется, цвет и
|
||||
типографика становятся другими. На пространстве с `bg` дефект маскируется,
|
||||
потому что SVG-fallback уже запрещён условием `space.bg`.
|
||||
|
||||
## 4. Scope
|
||||
|
||||
- сделать `show_names: false` единым запретом постоянных room-labels в полном
|
||||
flat/iso View, Devices editor и компактной карточке пространства;
|
||||
- сохранить принудительную видимость редактируемой HTML-подписи в Plan editor;
|
||||
- сохранить live-preview значения в открытом диалоге настроек пространства;
|
||||
- при `show_names: true` не менять состав, позицию, масштаб, цвет, метрики,
|
||||
HA Area icon, drag/resize и навигацию комнатной карточки;
|
||||
- удалить или обезвредить ошибочные SVG-fallback renderer и актуализировать
|
||||
больше не существующий `.rlabel` styling-hook;
|
||||
- добавить browser regression, mutation gate, визуальное доказательство и
|
||||
пользовательскую/тестовую документацию.
|
||||
|
||||
## 5. Non-scope
|
||||
|
||||
- изменение текста/назначения переключателя или добавление второго режима
|
||||
«статические названия»;
|
||||
- скрытие названия комнаты внутри tooltip, диалога настроек, HA Area или
|
||||
accessibility-описания самой комнаты: настройка управляет подписями на плане;
|
||||
- удаление либо сброс `layout.rl_<roomId>`, масштаба подписи или room metrics;
|
||||
- изменение `show_borders`, room fill, Glow, openings, devices и room hover;
|
||||
- изменение дефолта `show_names` для новых/legacy пространств — это отдельная
|
||||
проблема #204;
|
||||
- schema/backend/API, migration, импорт/экспорт и Optimize;
|
||||
- публичное включение изометрии или изменение её геометрии;
|
||||
- редизайн комнатной карточки, Plan gear/handles или compact space card.
|
||||
|
||||
## 6. Контракт поведения
|
||||
|
||||
### 6.1. Матрица видимости
|
||||
|
||||
| Поверхность | `show_names: true` | `show_names: false` |
|
||||
|---|---|---|
|
||||
| Full View, flat | Одна HTML `.roomlabel` на именованную комнату | Нет HTML/SVG room-label |
|
||||
| Full View, hidden iso | Та же HTML `.roomlabel`, спроецированная существующей iso-логикой | Нет HTML/SVG room-label |
|
||||
| Devices editor | Одна HTML `.roomlabel` | Нет HTML/SVG room-label |
|
||||
| Plan editor | Одна редактируемая HTML `.roomlabel` | Та же editor-only `.roomlabel` |
|
||||
| Compact space card | Одна HTML `.roomlabel` | Нет HTML/SVG room-label |
|
||||
|
||||
Условие `!space.bg` больше не создаёт альтернативный способ показать имя.
|
||||
Наличие или отсутствие фонового изображения не влияет на матрицу.
|
||||
|
||||
### 6.2. Повторное включение
|
||||
|
||||
Выключение не удаляет `layout.rl_<roomId>` и room settings. После повторного
|
||||
включения карточка возвращается в сохранённую позицию и с сохранёнными
|
||||
`k/name_scale/label_scale`. Разрешённые `label_temp`, `label_hum`, `label_lqi`
|
||||
и `label_light` снова отображаются по существующим правилам и данным.
|
||||
|
||||
### 6.3. Plan editor
|
||||
|
||||
Plan editor сохраняет исключение `_markup`: подпись нужна для drag, resize и
|
||||
доступа к редактируемому имени. Это исключение не должно протекать в View после
|
||||
выхода из редактора. Room gear и placeholder безымянной комнаты сохраняются.
|
||||
|
||||
### 6.4. Диалог настроек
|
||||
|
||||
При переключении `showNames` в edit-диалоге `_spaceDisplayForRender()` сразу
|
||||
проецирует новое значение в затемнённый пользовательский View. Cancel возвращает
|
||||
persisted значение, Save записывает boolean. Результат после повторного открытия
|
||||
совпадает с сохранённым состоянием.
|
||||
|
||||
## 7. Данные, совместимость и styling hooks
|
||||
|
||||
Persisted-формат не меняется: `settings.show_names` уже валидируется и хранит
|
||||
boolean. Миграция не нужна, конфигурация не переписывается при чтении.
|
||||
|
||||
`div.roomlabel[data-hp="room-label"]` остаётся каноническим hook видимой
|
||||
подписи. `text.rlabel` существовал только в противоречащей настройке fallback-
|
||||
ветке и после исправления не является доступным runtime hook; строка о нём в
|
||||
`docs/STYLING-HOOKS.md` удаляется или заменяется честным описанием отсутствия
|
||||
подписи. `data-hp`, `data-id` и `data-area` HTML-карточки не меняются.
|
||||
|
||||
Downgrade возвращает старый SVG-fallback, но не теряет данные. Пользовательский
|
||||
CSS, намеренно показывавший `text.rlabel` при выключенных названиях, перестаёт
|
||||
иметь target — это необходимое следствие исправления ложного поведения, а не
|
||||
новая точка расширения.
|
||||
|
||||
## 8. UX, i18n, accessibility и touch
|
||||
|
||||
Новых строк и элементов управления нет. Существующий русский и английский
|
||||
текст становится честным. Выключенная подпись не оставляет пустого DOM-узла,
|
||||
focus target или невидимой pointer-зоны. Tooltip комнаты и room hover остаются
|
||||
доступны по геометрии комнаты, поэтому получить сведения по комнате можно.
|
||||
|
||||
Touch/keyboard policy и события Plan editor не меняются. При включённых именах
|
||||
существующие drag, resize handles, Area navigation и accessibility-описания
|
||||
сохраняются.
|
||||
|
||||
## 9. Acceptance criteria и доказательства
|
||||
|
||||
| AC | Критерий | Обязательное доказательство |
|
||||
|---|---|---|
|
||||
| AC1 | На нарисованном пространстве без `bg`, при `show_names:false`, в flat View нет ни `.roomlabel`, ни `.room-svg-labels text`, ни `[data-hp="room-label"]`. | Targeted Playwright smoke через реальный space setting. |
|
||||
| AC2 | AC1 выполняется в компактной карточке пространства. | Тот же smoke на `houseplan-space-card`. |
|
||||
| AC3 | Hidden iso при `show_names:false` не форсирует подписи; при `true` сохраняет существующую projected HTML-карточку. | Расширенный isometric contract/live smoke. |
|
||||
| AC4 | Plan editor показывает редактируемую подпись при `show_names:false`; после выхода View снова пуст. | Browser mode-transition smoke с DOM assertions. |
|
||||
| AC5 | При `true` HTML-карточки, метрики, HA Area icon, сохранённая позиция/scale и текущие события не меняются. | Существующие room-card/link/parity smokes + focused regression. |
|
||||
| AC6 | Toggle в edit-диалоге даёт live-preview, Save переживает повторное открытие, Cancel не пишет config. | Расширенный `smoke_space_settings.mjs` либо отдельный targeted smoke. |
|
||||
| AC7 | `show_borders`, fills, Glow, devices, openings и room tooltip не меняются при выключении имён. | DOM snapshot/assertions targeted smoke + reviewed golden. |
|
||||
| AC8 | Документация больше не обещает доступный `text.rlabel` hook и однозначно описывает переключатель. | Diff `STYLING-HOOKS`, user guide и `TESTING`. |
|
||||
| AC9 | Ошибочный fallback доказан исполняемым мутантом. | `mutation-gate --check`, clean green / mutant red. |
|
||||
| AC10 | Рабочие gates зелёные. | typecheck, unit, build и все затронутые targeted smokes. |
|
||||
|
||||
## 10. План автотестов
|
||||
|
||||
### 10.1. Unit/source contract
|
||||
|
||||
Новая pure-логика не требуется. Существующие unit `spaceDisplayOf` уже
|
||||
доказывают чтение явного `false`. Если итоговая реализация вынесет общую функцию
|
||||
матрицы видимости, добавить table-driven unit; иначе не дублировать Lit-template
|
||||
в искусственном source test.
|
||||
|
||||
### 10.2. Browser smoke
|
||||
|
||||
Расширить `demo/smoke_space_settings.mjs` или создать небольшой именной smoke:
|
||||
|
||||
1. взять пространство без `plan_url/bg`, включить имена и зафиксировать одну
|
||||
HTML-карточку с метрикой и сохранённой layout-позицией;
|
||||
2. открыть edit-диалог и выключить имена, проверить live-preview;
|
||||
3. Save и повторное открытие подтверждают `false` и отсутствие любых labels;
|
||||
4. перейти в Plan — подпись и editor affordance видимы; вернуться в View —
|
||||
снова скрыты;
|
||||
5. повторить ключевую проверку в hidden iso и compact space card;
|
||||
6. включить имена обратно и проверить восстановление карточки, позиции/scale и
|
||||
метрики;
|
||||
7. отдельно проверить Cancel и отсутствие `pageerror`/console error.
|
||||
|
||||
`demo/smoke_styling_hooks.mjs` меняет прежнее утверждение «SVG-label существует
|
||||
при false» на честное отсутствие любого label; HTML hook при true остаётся.
|
||||
Смежные `smoke_room_cards.mjs`, `smoke_room_link.mjs`, room-label parity и iso
|
||||
smokes прогоняются до code review.
|
||||
|
||||
### 10.3. Golden и mutation gate
|
||||
|
||||
Добавить/переиспользовать focused light/dark golden для нарисованного
|
||||
пространства: reviewed baseline при `false` не содержит имён, при `true`
|
||||
содержит существующие HTML-карточки. Общий `golden:verify` и полный smoke идут
|
||||
перед бетой, но затронутые focused кадры обязательны при реализации.
|
||||
|
||||
Mutation entry `hidden-room-names-svg-fallback` возвращает хотя бы одну
|
||||
ошибочную full/compact fallback-ветку. Targeted guard обязан быть зелёным на
|
||||
чистом коде и non-zero на мутанте. Если full и compact исправляются разными
|
||||
необщими ветками, нужны два mutants, чтобы каждый renderer умел независимо
|
||||
покраснеть.
|
||||
|
||||
## 11. Риски и меры
|
||||
|
||||
| Риск | Мера |
|
||||
|---|---|
|
||||
| Скрытие протечёт в Plan и лишит пользователя редактируемого имени. | Отдельная строка матрицы, AC4 и реальный переход режимов. |
|
||||
| Исправится full card, но останется compact или iso override. | Независимые AC2/AC3 и mutants по renderer. |
|
||||
| Повторное включение сбросит позицию/scale/metrics. | Запрет записи layout и round-trip AC5/AC6. |
|
||||
| Вместе с label исчезнет tooltip/room pointer geometry. | Label DOM меняется отдельно от room shape; AC7. |
|
||||
| Удалится документированный styling hook без объяснения. | Актуализация `STYLING-HOOKS` и compatibility note §7. |
|
||||
|
||||
Performance улучшается либо нейтрален: удаляются DOM/SVG nodes и map по комнатам
|
||||
при выключенном слое, новых проходов/таймеров/network calls нет. Security/privacy
|
||||
boundary не меняется; настройка не становится механизмом сокрытия данных.
|
||||
|
||||
## 12. Rollback
|
||||
|
||||
Frontend-изменение откатывается вместе с тестами и документацией одним
|
||||
коммитом. Данные и schema не меняются. Откат возвращает только ошибочный
|
||||
SVG-fallback/iso override и не требует восстановления config или layout.
|
||||
|
||||
## 13. Release-артефакты
|
||||
|
||||
- пользовательские записи в `docs/CHANGELOG.md` и `docs/CHANGELOG.ru.md` в
|
||||
implementation-коммите с `User-Visible: yes`;
|
||||
- обновления `docs/USER-GUIDE.ru.md`, `docs/STYLING-HOOKS.md` и
|
||||
`docs/TESTING.md`;
|
||||
- targeted full/compact/Plan/iso browser evidence, styling-hook regression и
|
||||
executable mutation gate;
|
||||
- focused reviewed light/dark golden и синхронные bundle snapshots;
|
||||
- отдельные backend, schema, migration, performance и security artifacts не
|
||||
нужны;
|
||||
- полные golden/smoke/performance остаются предрелизным гейтом.
|
||||
|
||||
## 14. Принятые предположения
|
||||
|
||||
Принято предположительно, поменять свободно при ревью:
|
||||
|
||||
1. «Скрыть названия» управляет постоянными labels на плане, но не удаляет имя
|
||||
из tooltip/диалогов и не является privacy-функцией.
|
||||
2. Plan editor сохраняет текущую принудительную видимость независимо от
|
||||
persisted `show_names`, потому что там имя является редактируемым объектом.
|
||||
3. Hidden iso обязан соблюдать тот же user setting, несмотря на прежний
|
||||
технический override `iso && !space.bg`.
|
||||
4. Канонический styling hook видимой подписи — существующий HTML
|
||||
`div.roomlabel`; отдельный статический режим и новый hook не добавляются.
|
||||
5. Если удаление мёртвого `.rlabel` CSS увеличит визуальный diff только за счёт
|
||||
отсутствующих nodes, это входит в задачу; прочая типографика не меняется.
|
||||
@@ -101,6 +101,7 @@ GitHub Issues и GitHub Projects (v2) остаются единственным
|
||||
| [#178](https://github.com/Matysh/houseplan-card/issues/178) Выбор сущности для действия «Переключить состояние» | [178-toggle-entity.md](178-toggle-entity.md) |
|
||||
| [#197](https://github.com/Matysh/houseplan-card/issues/197) Один junction-патч не гасит кладку всего плана | [197-junction-patch-fail-dark.md](197-junction-patch-fail-dark.md) |
|
||||
| [#201](https://github.com/Matysh/houseplan-card/issues/201) Наследование толщины для атомарного участка стены | [201-atomic-thickness-lookup.md](201-atomic-thickness-lookup.md) |
|
||||
| [#203](https://github.com/Matysh/houseplan-card/issues/203) Выключение названий скрывает все подписи комнат | [203-hide-room-names.md](203-hide-room-names.md) |
|
||||
| [#186](https://github.com/Matysh/houseplan-card/issues/186) Безопасный остаток стены у торцов партиционного проёма | [186-partition-opening-jamb-margin.md](186-partition-opening-jamb-margin.md) |
|
||||
|
||||
## P3
|
||||
|
||||
Reference in New Issue
Block a user