feat(editor): the simulation opens sheets, not windows in the window

A tap on a device in the simulation now only chooses it; its three-dot
button (or a long press) opens what Java's click opened: the desktop, and
newly a switch's SAT table and a home router's NAT table, beside each
card's data exchange.

The desktop, the tables and the data exchange are no windows in the
window any more but the simulation's sheet (SimulationSheet), after the
dashboard's AppSheet: below the toolbar to the bottom, a head with icon,
title, who else has it open, see-through and close. One at a time — it
covers the surface. It stays over a return to the design with the program
open on a desktop; a sheet whose device was removed closes. See-through
fades the body (0.55) and keeps the head; the choice is kept in the
browser. Java opens these as movable windows, several at once, with a
click; named in CHANGES.md.

Tests open through the menu (showFromMenu, showDesktop in editorPage.ts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-10 17:18:25 +00:00
co-authored by Claude Opus 5.5
parent 1593726447
commit 16d9cc2095
26 changed files with 585 additions and 497 deletions
+4 -6
View File
@@ -9,7 +9,7 @@
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { expect, test, type Page } from '@playwright/test';
import { drawing, onDevice, serveEditor } from './editorPage.js';
import { drawing, onDevice, serveEditor, showDesktop } from './editorPage.js';
let server: { readonly base: string; readonly close: () => Promise<void> };
@@ -40,9 +40,7 @@ async function openPages(page: Page): Promise<void> {
/** A computer's desktop, opened with a tap. */
async function desktopOf(page: Page, name: string) {
const id = (await drawing(page)).nodes.find((node) => node.name === name)!.id;
const at = await onDevice(page, id);
await page.mouse.click(at.x, at.y);
return page.locator(`section[data-desktop="${id}"]`);
return showDesktop(page, id);
}
test('writes a page into the web server, which serves it while the simulation runs, and changes it there', async ({ page }) => {
@@ -88,7 +86,7 @@ test('writes a page into the web server, which serves it while the simulation ru
// The other computer's browser fetches it from the running web server (the desktops closed in between, which covered the computers).
const fetchPage = async (expected: string) => {
await desktop.locator('.desktop-close').click();
await desktop.locator('.simulation-sheet__close').click();
const browserDesktop = await desktopOf(page, 'Browser');
await browserDesktop.locator('[data-program="webBrowser"]').click();
const browser = browserDesktop.locator('[data-program-window="webBrowser"]');
@@ -96,7 +94,7 @@ test('writes a page into the web server, which serves it while the simulation ru
await address.fill('192.168.0.20/neu.html');
await address.press('Enter');
await expect(browser.frameLocator('iframe[title="Seite"]').locator('body')).toHaveText(expected, { timeout: 30_000 });
await browserDesktop.locator('.desktop-close').click();
await browserDesktop.locator('.simulation-sheet__close').click();
await desktopOf(page, 'Server');
await desktop.locator('[data-program="textEditor"]').click();
};