From a7f1c01443d5448784c0f63ee796b7a994c9bb4b Mon Sep 17 00:00:00 2001 From: Evgeny Boger Date: Wed, 2 Sep 2026 21:21:07 +0000 Subject: [PATCH 1/4] feat(dali): sendCellValueUpdate helper for control writes The `/on` command topic was spelled inside DevicesStore. The DALI page's embedded controls drive cells without that store, so the one spelling moves into a helper both use. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01BNC4oayJWjJaHMmvM8YMGC --- frontend/src/stores/devices/devices-store.ts | 4 ++-- frontend/src/stores/devices/send-cell-value.ts | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 frontend/src/stores/devices/send-cell-value.ts diff --git a/frontend/src/stores/devices/devices-store.ts b/frontend/src/stores/devices/devices-store.ts index ad499aa48..4ee2366c2 100644 --- a/frontend/src/stores/devices/devices-store.ts +++ b/frontend/src/stores/devices/devices-store.ts @@ -4,6 +4,7 @@ import { mqttClient } from '@/services'; import Cell from './cell'; import Device from './device'; import { isTopicsAreEqual, splitTopic } from './helpers'; +import { sendCellValueUpdate } from './send-cell-value'; import type { ValueType } from './types'; export default class DevicesStore { @@ -168,8 +169,7 @@ export default class DevicesStore { } async sendCellValueUpdate(deviceId: string, controlId: string, value: string) { - const topic = `/devices/${deviceId}/controls/${controlId}/on`; - await mqttClient.send(topic, value, false); + await sendCellValueUpdate(deviceId, controlId, value); } #getOrCreateTopics(deviceId: string) { diff --git a/frontend/src/stores/devices/send-cell-value.ts b/frontend/src/stores/devices/send-cell-value.ts new file mode 100644 index 000000000..ab2f244ce --- /dev/null +++ b/frontend/src/stores/devices/send-cell-value.ts @@ -0,0 +1,10 @@ +import { mqttClient } from '@/services'; + +/** + * Publish a control write the way every WB daemon expects it — non-retained, + * on the `/on` command topic. The one spelling of that topic, shared by + * DevicesStore and the DALI page's embedded controls. + */ +export async function sendCellValueUpdate(deviceId: string, controlId: string, value: string) { + await mqttClient.send(`/devices/${deviceId}/controls/${controlId}/on`, value, false); +} From af772ffb05c8c404a383841bc8c15588c698f735 Mon Sep 17 00:00:00 2001 From: Evgeny Boger Date: Mon, 31 Aug 2026 14:52:01 +0000 Subject: [PATCH 2/4] feat(dali): live device controls on device, group and bus pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commissioning a lamp is one half of the job; the other is seeing it react. Each device page now carries the daemon's live controls for that device — a featured strip of what one reaches for first (level, colour, colour temperature, on/off) and the rest behind "All controls"; a group page shows the group's virtual device, a bus page the bus's broadcast device. The strip reuses the dashboard Cell components, so a control behaves exactly as it does on the Devices page. The tab toolbar gains the page's title: on mobile the tree is hidden while a page is open, so nothing else said what was on screen. Its buttons wrap on phone widths instead of stacking on top of each other. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01BNC4oayJWjJaHMmvM8YMGC --- debian/changelog | 9 + .../collapsible-panel-toggle.test.tsx | 20 ++ .../collapsible-panel/collapsible-panel.tsx | 10 +- frontend/src/i18n/locales/en.json | 3 + frontend/src/i18n/locales/ru.json | 3 + .../dali/components/bus-commands/styles.css | 10 +- .../bus-tab-content/bus-tab-content.tsx | 24 +- .../device-controls/device-controls.tsx | 307 ++++++++++++++++++ .../device-controls/featured.test.ts | 93 ++++++ .../dali/components/device-controls/index.ts | 2 + .../components/device-controls/styles.css | 174 ++++++++++ .../dali/components/device-controls/types.ts | 11 + .../device-tab-content/device-tab-content.tsx | 11 +- .../group-tab-content/group-tab-content.tsx | 8 +- .../dali/components/tab-toolbar/index.ts | 1 + .../components/tab-toolbar/tab-toolbar.tsx | 36 ++ .../dali/components/tab-toolbar/types.ts | 3 + .../src/pages/settings/configs/dali/dali.tsx | 32 +- .../pages/settings/configs/dali/styles.css | 36 ++ .../stores/dali/device-store-controls.test.ts | 27 ++ frontend/src/stores/dali/device-store.ts | 4 + .../stores/dali/group-store-mqtt-id.test.ts | 19 ++ frontend/src/stores/dali/group-store.ts | 13 + 23 files changed, 833 insertions(+), 23 deletions(-) create mode 100644 frontend/src/components/collapsible-panel/collapsible-panel-toggle.test.tsx create mode 100644 frontend/src/pages/settings/configs/dali/components/device-controls/device-controls.tsx create mode 100644 frontend/src/pages/settings/configs/dali/components/device-controls/featured.test.ts create mode 100644 frontend/src/pages/settings/configs/dali/components/device-controls/index.ts create mode 100644 frontend/src/pages/settings/configs/dali/components/device-controls/styles.css create mode 100644 frontend/src/pages/settings/configs/dali/components/device-controls/types.ts create mode 100644 frontend/src/pages/settings/configs/dali/components/tab-toolbar/index.ts create mode 100644 frontend/src/pages/settings/configs/dali/components/tab-toolbar/tab-toolbar.tsx create mode 100644 frontend/src/pages/settings/configs/dali/components/tab-toolbar/types.ts create mode 100644 frontend/src/stores/dali/device-store-controls.test.ts create mode 100644 frontend/src/stores/dali/group-store-mqtt-id.test.ts diff --git a/debian/changelog b/debian/changelog index 6c850526f..c62de7108 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +wb-mqtt-homeui (2.250.4) stable; urgency=medium + + * DALI: live device controls on device, group and bus pages — a featured strip + of the controls one reaches for (level, colour, temperature, on/off) with + the rest behind "All controls"; the page toolbar names what is open, which + the hidden tree no longer does on mobile, and its buttons wrap on phones + + -- Wiren Board Robot Mon, 31 Aug 2026 20:40:00 +0300 + wb-mqtt-homeui (2.249.3) stable; urgency=medium * Fix autologin being switched off when the autologin user is edited diff --git a/frontend/src/components/collapsible-panel/collapsible-panel-toggle.test.tsx b/frontend/src/components/collapsible-panel/collapsible-panel-toggle.test.tsx new file mode 100644 index 000000000..c16bef26e --- /dev/null +++ b/frontend/src/components/collapsible-panel/collapsible-panel-toggle.test.tsx @@ -0,0 +1,20 @@ +// @vitest-environment happy-dom +import { fireEvent, render, screen } from '@testing-library/react'; +import { CollapsiblePanel } from './collapsible-panel'; + +describe('CollapsiblePanel: the whole title row toggles, exactly once per click', () => { + it('clicking the title text collapses and expands the body', () => { + render(
body
); + expect(screen.getByText('body')).toBeTruthy(); + fireEvent.click(screen.getByText('Broadcast settings')); + expect(screen.queryByText('body')).toBeNull(); + fireEvent.click(screen.getByText('Broadcast settings')); + expect(screen.getByText('body')).toBeTruthy(); + }); + + it('the toggle row is not a