diff --git a/cypress/fixtures/flows/dashboard-switches.json b/cypress/fixtures/flows/dashboard-switches.json index c505bdc5d..89c045ae3 100644 --- a/cypress/fixtures/flows/dashboard-switches.json +++ b/cypress/fixtures/flows/dashboard-switches.json @@ -253,5 +253,104 @@ "test-helper" ] ] + }, + { + "id": "dashboard-ui-group-3", + "type": "ui-group", + "name": "Group 3", + "page": "dashboard-ui-page-1", + "width": "6", + "height": "1", + "order": -1, + "showTitle": true, + "className": "", + "visible": "true", + "disabled": "false" + }, + { + "id": "dashboard-ui-button-show-input-on", + "type": "ui-button", + "z": "node-red-tab-switches", + "group": "dashboard-ui-group-3", + "name": "", + "label": "Button - On (bool)", + "order": 0, + "width": 0, + "height": 0, + "tooltip": "", + "color": "", + "bgcolor": "", + "className": "", + "icon": "", + "payload": "true", + "payloadType": "bool", + "topic": "", + "topicType": "str", + "x": 90, + "y": 420, + "wires": [ + [ + "dashboard-ui-switch-show-input" + ] + ] + }, + { + "id": "dashboard-ui-button-show-input-off", + "type": "ui-button", + "z": "node-red-tab-switches", + "group": "dashboard-ui-group-3", + "name": "", + "label": "Button - Off (bool)", + "order": 0, + "width": 0, + "height": 0, + "tooltip": "", + "color": "", + "bgcolor": "", + "className": "", + "icon": "", + "payload": "false", + "payloadType": "bool", + "topic": "", + "topicType": "str", + "x": 90, + "y": 460, + "wires": [ + [ + "dashboard-ui-switch-show-input" + ] + ] + }, + { + "id": "dashboard-ui-switch-show-input", + "type": "ui-switch", + "z": "node-red-tab-switches", + "name": "", + "label": "Show Input", + "group": "dashboard-ui-group-3", + "order": 0, + "width": "3", + "height": "1", + "passthru": false, + "decouple": true, + "topic": "topic", + "topicType": "str", + "style": "", + "className": "", + "onvalue": "on", + "onvalueType": "str", + "onicon": "", + "oncolor": "", + "offvalue": "off", + "offvalueType": "str", + "officon": "", + "offcolor": "", + "x": 300, + "y": 440, + "wires": [ + [ + "test-helper" + ] + ] } ] \ No newline at end of file diff --git a/cypress/tests/widgets/switch.spec.js b/cypress/tests/widgets/switch.spec.js index fc4782408..9c5fe79c8 100644 --- a/cypress/tests/widgets/switch.spec.js +++ b/cypress/tests/widgets/switch.spec.js @@ -89,3 +89,40 @@ describe('Node-RED Dashboard 2.0 - Switches with Icons', () => { cy.checkOutput('msg.payload', 'off') }) }) + +describe('Node-RED Dashboard 2.0 - Switches in "Show Input" mode', () => { + beforeEach(() => { + cy.deployFixture('dashboard-switches') + cy.visit('/dashboard/page1') + }) + + it('can be set to the on state via incoming payload and does not pass on the value', () => { + cy.resetContext() + cy.clickAndWait(cy.get('#nrdb-ui-widget-dashboard-ui-button-show-input-on')) + + // Emitting strings + cy.get('#nrdb-ui-widget-dashboard-ui-switch-show-input').find('.v-input.v-input--horizontal').should('have.class', 'v-switch') + cy.get('#nrdb-ui-widget-dashboard-ui-switch-show-input').find('.v-input.v-input--horizontal').should('have.class', 'active') + + cy.checkOutput('msg', undefined) + }) + + it('is put into loading state when clicked, and resets to pre-click state on a page refresh', () => { + // set to off + cy.clickAndWait(cy.get('#nrdb-ui-widget-dashboard-ui-button-show-input-on')) + + // click the switch directly + cy.get('#nrdb-ui-widget-dashboard-ui-switch-show-input').find('input').click() + + // put into loading state + cy.get('#nrdb-ui-widget-dashboard-ui-switch-show-input').find('.v-input.v-input--horizontal').should('have.class', 'v-switch--loading') + + // should now be off + cy.checkOutput('msg.payload', 'off') + + cy.reload() + + // on refresh, status is reset to pre-click state + cy.get('#nrdb-ui-widget-dashboard-ui-switch-show-input').find('.v-input.v-input--horizontal').should('have.class', 'active') + }) +}) diff --git a/nodes/store/data.js b/nodes/store/data.js index 5d2674663..32810d148 100644 --- a/nodes/store/data.js +++ b/nodes/store/data.js @@ -44,7 +44,7 @@ const getters = { }, // given a widget id, return the latest msg received msg (id) { - return data[id] + return config.RED.util.cloneMessage(data[id]) } } diff --git a/nodes/widgets/ui_switch.js b/nodes/widgets/ui_switch.js index f110bc41d..9ae5373a6 100644 --- a/nodes/widgets/ui_switch.js +++ b/nodes/widgets/ui_switch.js @@ -21,16 +21,6 @@ module.exports = function (RED) { // ensure we have latest instance of the widget's node const wNode = RED.nodes.getNode(node.id) - if (!config.passthru && config.decouple) { - return - } - - node.status({ - fill: value ? 'green' : 'red', - shape: 'ring', - text: value ? states[1] : states[0] - }) - // retrieve the assigned on/off value const on = RED.util.evaluateNodeProperty(config.onvalue, config.onvalueType, wNode) const off = RED.util.evaluateNodeProperty(config.offvalue, config.offvalueType, wNode) @@ -40,10 +30,19 @@ module.exports = function (RED) { msg = await appendTopic(RED, config, node, msg) } - datastore.save(group.getBase(), node, msg) + if (!config.passthru && config.decouple) { + wNode.send(msg) + } else { + node.status({ + fill: value ? 'green' : 'red', + shape: 'ring', + text: value ? states[1] : states[0] + }) + datastore.save(group.getBase(), node, msg) - // simulate Node-RED node receiving an input - wNode.send(msg) + // simulate Node-RED node receiving an input + wNode.send(msg) + } }, onInput: async function (msg, send) { let error = null