${space.rooms.map((room) => {\n'
+ ' const center = roomCenter(room);\n'
@@ -7397,7 +7397,7 @@ const MUTANT_DEFINITIONS = [
+ ' ${decorImages}\n'
+ ' ${stairShapes}\n'
+ ' ${glowPools}\n'
- + ' ${wallUnion',
+ + ' ${leds.size',
}],
},
{
@@ -13741,8 +13741,9 @@ const MUTANT_DEFINITIONS = [
+ 'Перевёрнутое условие закрывает «грязный» диалог молча и спрашивает у чистого',
patches: [{
file: 'src/editors/marker-dialog.ts',
- find: " if (!edit || !dirty) { forgetMarkerBaseline(this.host); this._closeMarkerDialog(); return; }",
- replace: " if (!edit || dirty) { forgetMarkerBaseline(this.host); this._closeMarkerDialog(); return; }",
+ // #780: the guard is the dialog's shared `leave` (close and the LED representation switch).
+ find: " if (edit && dirty && !await this.host._confirmDanger({",
+ replace: " if ((!edit || !dirty) && !await this.host._confirmDanger({",
}],
},
{
diff --git a/src/editors/marker-dialog.ts b/src/editors/marker-dialog.ts
index 2fcd78fc..9dbbeb3a 100644
--- a/src/editors/marker-dialog.ts
+++ b/src/editors/marker-dialog.ts
@@ -168,17 +168,21 @@ export function renderMarkerDialog(this: HouseplanEditorRuntime): TemplateResult
&& (edit ? dirty : true);
const saveTitle = problems[0] ? st(problems[0].message)
: bindingUnverified && !!d.binding && d.binding !== 'virtual' ? t('marker.ha_registry_limited') : '';
- const requestClose = async (event: Event) => {
- if (!edit || !dirty) { forgetMarkerBaseline(this.host); this._closeMarkerDialog(); return; }
- const dialog = event.currentTarget as { rejectClose?: () => void } | null;
- const discard = await this.host._confirmDanger({
+ // #780: the same save/discard guard also runs before a representation change.
+ const leave = async () => {
+ if (edit && dirty && !await this.host._confirmDanger({
key: 'discard-marker-dialog', kind: 'warning',
title: st('dialog.discard_title'), message: st('dialog.discard_message'),
objectName: d.name.trim() || previewDevice?.name || undefined,
confirmLabel: st('dialog.discard_confirm'), cancelLabel: st('dialog.discard_keep'),
icon: 'mdi:content-save-off-outline', confirmIcon: 'mdi:content-save-off-outline',
- });
- if (discard) { forgetMarkerBaseline(this.host); this._closeMarkerDialog(); } else dialog?.rejectClose?.();
+ })) return false;
+ forgetMarkerBaseline(this.host); this._closeMarkerDialog();
+ return true;
+ };
+ const requestClose = async (event: Event) => {
+ const dialog = event.currentTarget as { rejectClose?: () => void } | null;
+ if (!await leave()) dialog?.rejectClose?.();
};
const reviewFirst = () => {
const first = problems[0];
@@ -860,7 +864,7 @@ export function renderMarkerDialog(this: HouseplanEditorRuntime): TemplateResult
.badge=${previewDevice ? this.host._spaceModelById(previewDevice.space)?.title ?? '' : this.host._spaceModel()?.title ?? ''}
icon="mdi:shape-plus" wide @hp-close=${requestClose}>
- ${basics}${tap}${light}${appearance}${details}
+ ${basics}${d.devId ? this.host._ledSection(d.devId, leave) : nothing}${tap}${light}${appearance}${details}