mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 11:49:16 +00:00
fix: keep ordinary marker dialog close synchronous
User-Visible: no Issue: #485
This commit is contained in:
@@ -190,6 +190,7 @@ import {
|
||||
radarAfterBindingChange, radarConfigFromDraft, radarDraft, recognizeRadar,
|
||||
type RadarEditorDraft,
|
||||
} from './radar-editor';
|
||||
import { finishMarkerDialogClose } from './marker-dialog-close';
|
||||
import { renderRadarSection } from './editors/radar-section';
|
||||
import { radarDiscardRequest, RadarSetupController } from './radar-setup';
|
||||
import {
|
||||
@@ -7327,25 +7328,18 @@ public _openDeviceInbox(): void {
|
||||
};
|
||||
}
|
||||
|
||||
public _closeMarkerDialog(): void { void this._closeMarkerDialogGuarded(); }
|
||||
public _closeMarkerDialog(): void {
|
||||
if (this._radarSetup.isDirty()) { void this._closeMarkerDialogGuarded(); return; }
|
||||
this._radarSetup.reset();
|
||||
finishMarkerDialogClose(this.host);
|
||||
}
|
||||
private async _closeMarkerDialogGuarded(): Promise<void> {
|
||||
if (!await this._radarSetup.discardIfAllowed()) {
|
||||
if (!await this._radarSetup.discardIfAllowed()) {
|
||||
await this.host.updateComplete; this.host.renderRoot
|
||||
.querySelector<HpDialog>('#marker-dialog')?.rejectClose();
|
||||
return;
|
||||
}
|
||||
this.host._markerDialog = null;
|
||||
if (this.host._deviceInboxReturn) {
|
||||
const restored = { ...this.host._deviceInboxReturn };
|
||||
this.host._deviceInbox = restored;
|
||||
this.host._deviceInboxReturn = null;
|
||||
if (restored.anchor) {
|
||||
void this.host.updateComplete.then(() => requestAnimationFrame(() => {
|
||||
const selector = `.device-inbox-row[data-binding="${CSS.escape(restored.anchor!)}"]`;
|
||||
this.host.renderRoot.querySelector<HTMLElement>(selector)?.scrollIntoView({ block: 'nearest' });
|
||||
}));
|
||||
}
|
||||
}
|
||||
this._closeMarkerDialog();
|
||||
}
|
||||
|
||||
public _deviceInboxCandidates(showEntities: boolean) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
interface MarkerDialogCloseHost<T extends { anchor?: string | null }> {
|
||||
_markerDialog: unknown | null;
|
||||
_deviceInboxReturn: T | null;
|
||||
_deviceInbox: T | null;
|
||||
updateComplete: Promise<unknown>;
|
||||
renderRoot: ParentNode;
|
||||
}
|
||||
|
||||
export function finishMarkerDialogClose<T extends { anchor?: string | null }>(
|
||||
host: MarkerDialogCloseHost<T>,
|
||||
): void {
|
||||
host._markerDialog = null;
|
||||
if (!host._deviceInboxReturn) return;
|
||||
const restored = { ...host._deviceInboxReturn } as T;
|
||||
host._deviceInbox = restored;
|
||||
host._deviceInboxReturn = null;
|
||||
if (!restored.anchor) return;
|
||||
void host.updateComplete.then(() => requestAnimationFrame(() => {
|
||||
const selector = `.device-inbox-row[data-binding="${CSS.escape(restored.anchor!)}"]`;
|
||||
host.renderRoot.querySelector<HTMLElement>(selector)?.scrollIntoView({ block: 'nearest' });
|
||||
}));
|
||||
}
|
||||
@@ -140,6 +140,10 @@ export class RadarSetupController {
|
||||
|
||||
public isActive(): boolean { return this.active !== null; }
|
||||
|
||||
public isDirty(): boolean {
|
||||
return !!this.active && (this.active.mount !== null || this.active.phase !== 'mount');
|
||||
}
|
||||
|
||||
public syncMarker(markerId: string): void {
|
||||
if (this.active && this.active.markerId !== markerId) this.reset();
|
||||
}
|
||||
|
||||
@@ -26,9 +26,11 @@ test('on-plan installation changes only the editor draft until ordinary Save', (
|
||||
confirmDiscard: async () => true,
|
||||
});
|
||||
assert.equal(controller.begin('radar', draft(), {
|
||||
id: 'living', name: 'Living', poly: [[0, 0], [1, 0], [1, 1], [0, 1]],
|
||||
id: 'living', name: 'Living', poly: [[0, 0], [1, 0], [1, 1], [0, 1]],
|
||||
}, 5, 7), true);
|
||||
assert.equal(controller.isDirty(), false, 'an untouched setup may close synchronously');
|
||||
controller.choosePoint(pointer(250, 400));
|
||||
assert.equal(controller.isDirty(), true, 'placing the mount makes the setup discard-sensitive');
|
||||
controller.choosePoint(pointer(250, 100));
|
||||
assert.equal(applied, null, 'the setup surface must not persist or apply before confirmation');
|
||||
controller.apply();
|
||||
@@ -54,6 +56,7 @@ test('cancelling calibration releases its draft subscription exactly once', asyn
|
||||
assert.equal(await controller.cancel(), true);
|
||||
assert.equal(await controller.cancel(), true);
|
||||
assert.equal(calls, 1);
|
||||
assert.equal(controller.isDirty(), false);
|
||||
});
|
||||
|
||||
test('dirty calibration stays open when discard confirmation is rejected', async () => {
|
||||
|
||||
Reference in New Issue
Block a user