ux v1.4.2: grid pitch halved (GRID_N=120), grid dots rendered above plan, dacha rooms snapped to grid nodes (instance data via config/set)

This commit is contained in:
JB
2026-07-04 11:37:25 +03:00
parent 13200ffc20
commit 609872b7b8
7 changed files with 46 additions and 22 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ FRONTEND_URL = "/houseplan_files/houseplan-card.js"
PLANS_URL = "/houseplan_files/plans" PLANS_URL = "/houseplan_files/plans"
PLANS_DIR = "houseplan/plans" # относительно каталога конфигурации HA PLANS_DIR = "houseplan/plans" # относительно каталога конфигурации HA
CONF_ADMIN_ONLY = "admin_only" CONF_ADMIN_ONLY = "admin_only"
VERSION = "1.4.0" VERSION = "1.4.2"
DEFAULT_CONFIG: dict = { DEFAULT_CONFIG: dict = {
"spaces": [], "spaces": [],
File diff suppressed because one or more lines are too long
+8 -6
View File
File diff suppressed because one or more lines are too long
+9
View File
@@ -1,5 +1,14 @@
# Changelog # Changelog
## v1.4.2 — 2026-07-04 (сетка разметки)
- Шаг сетки уменьшен в 2 раза: GRID_N 60 → 120 (шаг 8.33 рендер-ед. ≈ 0.83% ширины плана).
- Точки сетки рендерятся ПОВЕРХ плана и комнат (grid-rect перенесён из под-плана в верхний
markup-слой); точки контрастнее (r=0.14g, обводка).
- Данные дачи: границы всех 13 комнат привязаны к узлам сетки (снап рёбер, сдвиги ≤ полшага;
правка только конфига инстанса через houseplan/config/set, код не менялся).
- Кэш карточки: URL модуля ?v= берётся из const.VERSION — при обновлении фронтенда бампать
const.py и рестартовать HA, иначе браузеры держат старый модуль в memory-cache.
## v1.4.1 — 2026-07-04 (UX разметки) ## v1.4.1 — 2026-07-04 (UX разметки)
- Esc / Ctrl+Z при рисовании убирают последнюю точку (и её линию, если она была добавлена - Esc / Ctrl+Z при рисовании убирают последнюю точку (и её линию, если она была добавлена
этим шагом; переиспользованные чужие стены не трогаются). этим шагом; переиспользованные чужие стены не трогаются).
+9
View File
@@ -38,6 +38,15 @@ cp dist/houseplan-card.js custom_components/houseplan/frontend/
- После деплоя JS — проверить в браузере (Ctrl+F5) и console (не должно быть ошибок из - После деплоя JS — проверить в браузере (Ctrl+F5) и console (не должно быть ошибок из
houseplan-card.js; битый бандл роняет все дашборды). houseplan-card.js; битый бандл роняет все дашборды).
## Кэш фронтенда и «пустой вид»
- URL модуля карточки содержит `?v=<VERSION из const.py>`. Браузеры держат ES-модуль в
memory-cache: после деплоя нового JS **бампните VERSION в const.py и рестартуйте HA**,
иначе обычный F5 оставит старую версию.
- После reload страницы HA-фронтенд (с kiosk-mode) иногда оставляет вид пустым
(«InvalidStateError: Transition was aborted», hui-view не создаётся 1–2 мин).
Лечится повторной SPA-навигацией: pushState + событие location-changed, или подождать.
## Релиз ## Релиз
Тег `vX.Y.Z` + GitHub Release → workflow `.github/workflows/release.yml` собирает и прикладывает Тег `vX.Y.Z` + GitHub Release → workflow `.github/workflows/release.yml` собирает и прикладывает
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "houseplan-card", "name": "houseplan-card",
"version": "1.4.1", "version": "1.4.2",
"description": "Interactive house plan Lovelace card for Home Assistant (dacha Kirillovskoe)", "description": "Interactive house plan Lovelace card for Home Assistant (dacha Kirillovskoe)",
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",
+10 -8
View File
@@ -12,7 +12,7 @@ import { FLOOR_BG, FLOOR_BG_RECT } from './data/backgrounds';
import { EXCLUDED_DOMAINS, GROUP_TITLES, iconFor, DOMAIN_PRIORITY } from './rules'; import { EXCLUDED_DOMAINS, GROUP_TITLES, iconFor, DOMAIN_PRIORITY } from './rules';
import './editor'; import './editor';
const CARD_VERSION = '1.4.1'; const CARD_VERSION = '1.4.2';
const LS_KEY = 'houseplan_card_layout_v1'; const LS_KEY = 'houseplan_card_layout_v1';
const NORM_W = 1000; // ширина рендер-пространства для нормированных конфигов const NORM_W = 1000; // ширина рендер-пространства для нормированных конфигов
@@ -33,7 +33,7 @@ interface RoomCfg {
poly?: number[][]; // полигон в рендер-единицах (модель) / нормированный (конфиг) poly?: number[][]; // полигон в рендер-единицах (модель) / нормированный (конфиг)
} }
const GRID_N = 60; // точек сетки по ширине плана const GRID_N = 120; // точек сетки по ширине плана
type MarkupTool = 'draw' | 'erase' | 'delroom'; type MarkupTool = 'draw' | 'erase' | 'delroom';
interface SpaceModel { interface SpaceModel {
@@ -1170,9 +1170,9 @@ class HouseplanCard extends LitElement {
return [r.x! + r.w! / 2, r.y! + Math.min(r.w!, r.h!) * 0.1]; return [r.x! + r.w! / 2, r.y! + Math.min(r.w!, r.h!) * 0.1];
} }
private _renderMarkupDefs(vb: number[]): TemplateResult { private _renderMarkupDefs(_vb: number[]): TemplateResult {
const g = this._gridPitch; const g = this._gridPitch;
const dotR = g * 0.09; const dotR = g * 0.14;
return svg`<defs> return svg`<defs>
<pattern id="hp-grid" x="0" y="0" width="${g}" height="${g}" patternUnits="userSpaceOnUse"> <pattern id="hp-grid" x="0" y="0" width="${g}" height="${g}" patternUnits="userSpaceOnUse">
<circle cx="0" cy="0" r="${dotR}" class="griddot"></circle> <circle cx="0" cy="0" r="${dotR}" class="griddot"></circle>
@@ -1180,15 +1180,15 @@ class HouseplanCard extends LitElement {
<circle cx="0" cy="${g}" r="${dotR}" class="griddot"></circle> <circle cx="0" cy="${g}" r="${dotR}" class="griddot"></circle>
<circle cx="${g}" cy="${g}" r="${dotR}" class="griddot"></circle> <circle cx="${g}" cy="${g}" r="${dotR}" class="griddot"></circle>
</pattern> </pattern>
</defs> </defs>`;
<rect x="${vb[0]}" y="${vb[1]}" width="${vb[2]}" height="${vb[3]}" fill="url(#hp-grid)" pointer-events="none"></rect>`;
} }
private _renderMarkupLayer(_vb: number[]): TemplateResult { private _renderMarkupLayer(vb: number[]): TemplateResult {
const segs = this._segments; const segs = this._segments;
const path = this._path; const path = this._path;
const g = this._gridPitch; const g = this._gridPitch;
return svg` return svg`
<rect x="${vb[0]}" y="${vb[1]}" width="${vb[2]}" height="${vb[3]}" fill="url(#hp-grid)" pointer-events="none"></rect>
${segs.map((s) => svg`<line class="seg" x1="${s[0]}" y1="${s[1]}" x2="${s[2]}" y2="${s[3]}"></line>`)} ${segs.map((s) => svg`<line class="seg" x1="${s[0]}" y1="${s[1]}" x2="${s[2]}" y2="${s[3]}"></line>`)}
${path.length > 1 ${path.length > 1
? svg`<polyline class="pathline" points="${path.map((p) => p.join(',')).join(' ')}"></polyline>` ? svg`<polyline class="pathline" points="${path.map((p) => p.join(',')).join(' ')}"></polyline>`
@@ -1487,7 +1487,9 @@ class HouseplanCard extends LitElement {
} }
.griddot { .griddot {
fill: var(--hp-accent); fill: var(--hp-accent);
opacity: 0.45; opacity: 0.75;
stroke: rgba(0, 0, 0, 0.35);
stroke-width: 0.4;
} }
.seg { .seg {
stroke: var(--hp-accent); stroke: var(--hp-accent);