From 16d6348cec5c0ba6e17df09cbf9ce16822405f82 Mon Sep 17 00:00:00 2001 From: Pouzor Date: Sun, 19 Jul 2026 15:15:13 +0200 Subject: [PATCH 1/2] fix(yaml): round-trip show_port_numbers on export/import YAML export wrote per-side handle counts but never the show_port_numbers toggle, so the option was lost on re-import while connection points survived. ha-relevant: maybe Fixes #272 --- frontend/src/types/yaml.ts | 3 +++ .../src/utils/__tests__/exportYaml.test.ts | 8 ++++++ .../src/utils/__tests__/importYaml.test.ts | 26 +++++++++++++++++++ frontend/src/utils/exportYaml.ts | 3 +++ frontend/src/utils/importYaml.ts | 2 ++ 5 files changed, 42 insertions(+) diff --git a/frontend/src/types/yaml.ts b/frontend/src/types/yaml.ts index 02758f0..8e1e78e 100644 --- a/frontend/src/types/yaml.ts +++ b/frontend/src/types/yaml.ts @@ -34,4 +34,7 @@ export interface YamlNode { bottomHandles?: number leftHandles?: number rightHandles?: number + // Whether port-number labels are shown next to connection points. Only written + // when enabled so the toggle round-trips through export/import (issue #272). + showPortNumbers?: boolean } diff --git a/frontend/src/utils/__tests__/exportYaml.test.ts b/frontend/src/utils/__tests__/exportYaml.test.ts index 83a4ff2..c87afa6 100644 --- a/frontend/src/utils/__tests__/exportYaml.test.ts +++ b/frontend/src/utils/__tests__/exportYaml.test.ts @@ -208,4 +208,12 @@ describe('exportCanvasToYaml', () => { expect(entry).not.toHaveProperty('topHandles') expect(entry).not.toHaveProperty('leftHandles') }) + + it('exports showPortNumbers only when enabled (issue #272)', () => { + const on = (yaml.load(exportCanvasToYaml([makeNode({ label: 'On', type: 'server', show_port_numbers: true })], [])) as Record[])[0] + expect(on.showPortNumbers).toBe(true) + + const off = (yaml.load(exportCanvasToYaml([makeNode({ label: 'Off', type: 'server', show_port_numbers: false })], [])) as Record[])[0] + expect(off).not.toHaveProperty('showPortNumbers') + }) }) diff --git a/frontend/src/utils/__tests__/importYaml.test.ts b/frontend/src/utils/__tests__/importYaml.test.ts index 6b4db95..dfc481e 100644 --- a/frontend/src/utils/__tests__/importYaml.test.ts +++ b/frontend/src/utils/__tests__/importYaml.test.ts @@ -368,4 +368,30 @@ describe('parseYamlToCanvas', () => { expect(edges[0].targetHandle).toBe('top-t') expect(nodes.find((n) => n.data.label === 'Switch')!.data.bottom_handles).toBe(3) }) + + // Regression for issue #272. + it('restores the show-port-numbers toggle from YAML', () => { + const yaml = ` +- nodeType: server + label: "Server" + showPortNumbers: true +` + const { nodes } = parseYamlToCanvas(yaml, empty, emptyEdges) + expect(nodes.find((n) => n.data.label === 'Server')!.data.show_port_numbers).toBe(true) + }) + + it('round-trips show-port-numbers through export → import (issue #272)', () => { + const on: Node = { + id: 'on', type: 'server', position: { x: 0, y: 0 }, + data: { label: 'On', type: 'server', status: 'online', services: [], show_port_numbers: true }, + } + const off: Node = { + id: 'off', type: 'server', position: { x: 0, y: 0 }, + data: { label: 'Off', type: 'server', status: 'online', services: [] }, + } + const yamlStr = exportCanvasToYaml([on, off], []) + const { nodes } = parseYamlToCanvas(yamlStr, empty, emptyEdges) + expect(nodes.find((n) => n.data.label === 'On')!.data.show_port_numbers).toBe(true) + expect(nodes.find((n) => n.data.label === 'Off')!.data.show_port_numbers).toBeUndefined() + }) }) diff --git a/frontend/src/utils/exportYaml.ts b/frontend/src/utils/exportYaml.ts index f2a9772..75ef513 100644 --- a/frontend/src/utils/exportYaml.ts +++ b/frontend/src/utils/exportYaml.ts @@ -92,6 +92,9 @@ export function exportCanvasToYaml(nodes: Node[], edges: Edge Date: Sun, 19 Jul 2026 15:34:19 +0200 Subject: [PATCH 2/2] test(settings): wait for async config before asserting Save payload The Proxmox/Zigbee auto-sync Save tests clicked Save after only waiting for an unrelated field, so under CI load getConfig could resolve after the click and Save fired with the default sync_enabled=false. Wait for the toggle to reflect the loaded state first. --- .../src/components/modals/__tests__/SettingsModal.test.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/src/components/modals/__tests__/SettingsModal.test.tsx b/frontend/src/components/modals/__tests__/SettingsModal.test.tsx index 41f34fb..14b0dbc 100644 --- a/frontend/src/components/modals/__tests__/SettingsModal.test.tsx +++ b/frontend/src/components/modals/__tests__/SettingsModal.test.tsx @@ -131,6 +131,9 @@ describe('SettingsModal', () => { vi.mocked(proxmoxApi.saveConfig).mockResolvedValue({ data: {} } as never) render() await screen.findByDisplayValue('60') + // Wait for the async proxmox getConfig to hydrate the toggle before saving — + // otherwise Save can fire with the default sync_enabled=false under CI load. + await waitFor(() => expect(screen.getByLabelText('Toggle Proxmox auto-sync')).toBeChecked()) fireEvent.click(screen.getByRole('button', { name: 'Save' })) await waitFor(() => { expect(proxmoxApi.saveConfig).toHaveBeenCalledWith({ sync_enabled: true, sync_interval: 3600 }) @@ -174,6 +177,9 @@ describe('SettingsModal', () => { render() await screen.findByDisplayValue('60') await screen.findByText('Zigbee auto-sync') + // Wait for the async zigbee getConfig to hydrate the toggle before saving — + // otherwise Save can fire with the default sync_enabled=false under CI load. + await waitFor(() => expect(screen.getByLabelText('Toggle Zigbee auto-sync')).toBeChecked()) fireEvent.click(screen.getByRole('button', { name: 'Save' })) await waitFor(() => { expect(zigbeeApi.saveConfig).toHaveBeenCalledWith({ sync_enabled: true, sync_interval: 1800 })