mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-02 04:38:55 +00:00
feat(general): «Общие настройки» по референсу — серия 2 из четырёх (#600)
§5 SPEC.md референса. Семь карточек #598 остались, менялось содержимое: - Display — две полные строки с иконкой, подписью и тумблером справа; пояснение радара по §5.2 стало подписью строки (текст прежний, ключ переехал в ленивый словарь как gs.radar_show_live_hint, «?» у строки больше нет); - Zigbee links — заголовок и «?» функции (topology.help) рисует карточка, а блок hp-zigbee-topology-settings получил режим embedded: строка-тумблер, callout «сохраните настройку», подзаголовки ZHA / Zigbee2MQTT, поле тем и строки действий контролами набора. Заголовок больше не удваивается (дефект 1). Лист набора вносится в теневой корень компонента; токены --hpf-* наследуются с хоста. Прежний render без embedded не тронут — его держит контракт #459; - Room fill colors — три подзаголовка (Lights / Temperature / Zigbee signal, Q6) и плитки цвета по три в ряд: название на свотче, hex, число прозрачности; свотч — trigger прежнего hp-color-opacity (Q5); - Light-source glow — две плитки и поле радиуса с единицей внутри рамки; - Plan — плашка цвета стен, сегмент фона, при Static — плашка фона с Reset и подсказкой (тема / свой цвет); - Sun — gs.sun_missing остаётся callout'ом (К5); север: поле градусов с «°», ссылка Clear, «N» и компас 44 px справа — индикатор набора, но тянуть его по-прежнему можно (smoke_sun гоняет настоящий drag; старый 120-px SVG и его CSS в plan.styles.ts удалены); лучи — строка-тумблер с подписью; источник лучей — сегмент (sun-settings-view.ts переписан с <select> на segmented, логика та же); - Data — подзаголовки с «?» и строки действий набора. К10 (Q1): Save только при изменениях и без ошибок (радиус > 0, север 0–359), статус в футере, вопрос при закрытии с изменениями; снимок при открытии — editors/general-form-state.ts поверх общего editors/dialog-baseline.ts (на него же переведён space-form-state.ts). _settingsDialog не получил новых ключей. Удалено мёртвое: _renderColorRow (рантайм и карточка), .sunrow/.suncol, ключи gs.wall_group, gs.bg_group, gs.bg_theme, gs.radar_show_live.help(.aria) в четырёх локалях. Девять новых ключей — в i18n/settings. Смоки переписаны осознанно, с пометкой #600: smoke_general_settings (инвентарь по классам набора, подзаголовки .hpf-sub h4, пояснения под «?» и подписью, ни одного .rhint), smoke_sun (сегмент источника лучей вместо select, поле #gs-north, radius drag 18 px), smoke_backup_transfer (подзаголовок и строка действий), smoke_settings_dialog_cards (callout вместо .rhint). Новый фокусный свидетель demo/smoke_general_settings_form.mjs: семь карточек и отсутствие старой разметки, один заголовок у Zigbee, десять плиток, компас 44, цели 44, запись плиток/плашки/радиуса/севера/сегментов в свои ключи, Save/dirty/вопрос при закрытии. Мутанты: general-save-enabled-without-changes, general-tile-opacity-writes-a-neighbour-key, general-north-clear-writes-zero, topology-embedded-draws-its-own-heading; якоря state-callout-hidden-under-help и dialog-card-loses-its-heading переставлены на новую разметку. Контрактные тесты: houseplan-source.mjs приводит `host.` к `this.` и в телах вынесенных диалогов; color-picker — три явных showOpacity=true (плитки, плашка стены, цвет комнаты); счётчик производных .aria 35 → 34. Бюджет: стартовый граф 290 711 — потолок ОПУЩЕН 292 500 → 292 200 (ушёл 120-px компас из eager-листа и мёртвые ключи); ленивый редакторский 237 929 — потолок 236 300 → 238 600 с разбором в bundle-budget.mjs. Гейты: typecheck, build, bundle:sync, npm test 2792 pass, mutation-gate --check, семь смоков «Общих», smoke_color_picker_consumers без правок. Issue: #600 User-Visible: no
This commit is contained in:
@@ -296,7 +296,13 @@ export const LOW_HEADROOM_WARNING_BYTES = 15_000;
|
||||
// ленивого support-словаря в основной, потому что «?» читает его через `_t`.
|
||||
// Код диалогов остался в ленивом графе; вырос словарь, который там же и был.
|
||||
// Опущен до 291 400 в #593, поднят обратно осознанно — рост объяснён здесь.
|
||||
export const INITIAL_VIEW_GZIP_CEILING = 292_500;
|
||||
/**
|
||||
* #600, серия 2: 292 500 → 292 200 (замер 290 711). Стартовый граф похудел:
|
||||
* компас «Общих настроек» стал индикатором набора, его 120-px CSS ушёл из
|
||||
* eager-листа `plan.styles.ts`, а мёртвые ключи основного каталога удалены.
|
||||
* Потолок опущен, чтобы выигрыш не потерялся.
|
||||
*/
|
||||
export const INITIAL_VIEW_GZIP_CEILING = 292_200;
|
||||
export const INITIAL_VIEW_CEILING_BAND = 2_000;
|
||||
|
||||
/**
|
||||
@@ -401,8 +407,12 @@ export const LAZY_FURNITURE_ART_GZIP_CEILING = 17_900;
|
||||
* словарь `i18n/settings` на четыре локали (51 ключ × 4 ≈ 3,5 КБ gzip), который
|
||||
* раньше лёг бы в первый кадр. Старая разметка онбординга (300 строк) ушла,
|
||||
* но она была в другом графе. Строки и словарь — большая часть роста.
|
||||
* - серия 2: 236 300 → 238 600 (замер 237 929). «Общие настройки» по §5:
|
||||
* плитки цвета, встроенный режим блока Zigbee, dirty/валидация; девять новых
|
||||
* строк словаря на четыре локали. Старые `_renderColorRow`, `.sunrow/.suncol`
|
||||
* и 120-px компас удалены.
|
||||
*/
|
||||
export const LAZY_EDITOR_GZIP_CEILING = 236_300;
|
||||
export const LAZY_EDITOR_GZIP_CEILING = 238_600;
|
||||
export const LAZY_GRAPH_CEILING_BAND = 2_000;
|
||||
|
||||
/**
|
||||
|
||||
@@ -10269,9 +10269,10 @@ const MUTANT_DEFINITIONS = [
|
||||
}, {
|
||||
// Оба сообщения о состоянии — один контракт (К5), поэтому и мутант один:
|
||||
// спрятать под «?» можно каждое, и «поймано» обязано означать оба.
|
||||
// #600: сообщение — callout набора; спрятать его в title так же легко.
|
||||
file: 'src/editors/general-settings-dialog.ts',
|
||||
find: " ? html`<div class=\"rhint\">${this.host._t('gs.sun_missing')}</div>`",
|
||||
replace: " ? html`<span title=${this.host._t('gs.sun_missing')}></span>`",
|
||||
find: " ? callout({ kind: 'warning', role: 'status', text: t('gs.sun_missing') })",
|
||||
replace: " ? html`<span title=${t('gs.sun_missing')}></span>`",
|
||||
}],
|
||||
},
|
||||
{
|
||||
@@ -10281,8 +10282,8 @@ const MUTANT_DEFINITIONS = [
|
||||
+ 'Заголовок и есть то, ради чего задача делалась, и его потеря обязана краснеть',
|
||||
patches: [{
|
||||
file: 'src/editors/general-settings-dialog.ts',
|
||||
find: " title: this.host._t('gs.card_fills'),",
|
||||
replace: " title: '',",
|
||||
find: " title: t('gs.card_fills'),",
|
||||
replace: " title: '',",
|
||||
}],
|
||||
},
|
||||
{
|
||||
@@ -10345,6 +10346,51 @@ const MUTANT_DEFINITIONS = [
|
||||
replace: " checked: !d.hideDecor, onChange: (v) => set(port, { ...d, hideDecor: v }),",
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'general-save-enabled-without-changes',
|
||||
guard: 'node demo/smoke_general_settings_form.mjs',
|
||||
because: '#600 К10/AC6 (Q1) для «Общих настроек»: Save активен только при изменениях; '
|
||||
+ 'без dirty футер снова врёт о том, есть ли что сохранять',
|
||||
patches: [{
|
||||
file: 'src/editors/general-settings-dialog.ts',
|
||||
find: ' const canSave = dirty && problems.length === 0 && !d.busy;',
|
||||
replace: ' const canSave = problems.length === 0 && !d.busy;',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'general-tile-opacity-writes-a-neighbour-key',
|
||||
guard: 'node demo/smoke_general_settings_form.mjs',
|
||||
because: '#600 К1/AC3: у плитки цвета своё число прозрачности, и оно обязано писать '
|
||||
+ 'в свой цвет палитры. Восемь одинаковых плиток подряд — соседний ключ на глаз '
|
||||
+ 'не отличить, а в конфиг уедет чужая прозрачность',
|
||||
patches: [{
|
||||
file: 'src/editors/general-settings-dialog.ts',
|
||||
find: " onOpacity: (a) => this._setFillColor(key, { c: v.c, a }),",
|
||||
replace: " onOpacity: (a) => this._setFillColor(key === 'light_on' ? 'light_off' : key, { c: v.c, a }),",
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'general-north-clear-writes-zero',
|
||||
guard: 'node demo/smoke_general_settings_form.mjs',
|
||||
because: '#600 §5.2: «Clear» возвращает север в «не задан» (null), а не в 0°: ноль — '
|
||||
+ 'это направление, и лучи через окна с ним считаются, а с null — нет',
|
||||
patches: [{
|
||||
file: 'src/editors/general-settings-dialog.ts',
|
||||
find: "textLink(t('gs.north_clear'), () => set({ northDeg: null }))",
|
||||
replace: "textLink(t('gs.north_clear'), () => set({ northDeg: 0 }))",
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'topology-embedded-draws-its-own-heading',
|
||||
guard: 'node demo/smoke_general_settings_form.mjs',
|
||||
because: '#600 дефект 1: заголовок «Zigbee links» удваивался — карточка рисовала '
|
||||
+ 'свой, компонент внутри — свой. Встроенный режим обязан заголовок не рисовать',
|
||||
patches: [{
|
||||
file: 'src/hp-zigbee-topology-settings.ts',
|
||||
find: ' if (this.embedded) return this._renderEmbedded();',
|
||||
replace: ' if (this.embedded && this.savedEnabled) return this._renderEmbedded();',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'form-kit-segment-drops-radio-semantics',
|
||||
guard: 'node --test test/form-kit.test.mjs',
|
||||
|
||||
Reference in New Issue
Block a user