From 29c877055b4adc3bd0f3b0abfa166d2c9d7d056a Mon Sep 17 00:00:00 2001 From: Cliff Meyers Date: Wed, 27 Jul 2016 12:01:57 -0400 Subject: [PATCH] [JENKINS-35781] fix a bug where clicking on a favorite on the Branches tab instead triggered the modal to open. React eventing is fun... --- .../src/main/js/components/Branches.jsx | 17 ++++---- .../src/main/js/components/StopPropagation.js | 40 +++++++++++++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 blueocean-dashboard/src/main/js/components/StopPropagation.js diff --git a/blueocean-dashboard/src/main/js/components/Branches.jsx b/blueocean-dashboard/src/main/js/components/Branches.jsx index 4e3f80d5..6519849d 100644 --- a/blueocean-dashboard/src/main/js/components/Branches.jsx +++ b/blueocean-dashboard/src/main/js/components/Branches.jsx @@ -3,6 +3,7 @@ import { CommitHash, ReadableDate } from '@jenkins-cd/design-language'; import { LiveStatusIndicator, WeatherIcon } from '@jenkins-cd/design-language'; import Extensions from '@jenkins-cd/js-extensions'; import RunPipeline from './RunPipeline.jsx'; +import { StopPropagation } from './StopPropagation'; import { buildRunDetailsUrl } from '../util/UrlUtils'; const { object } = PropTypes; @@ -55,13 +56,15 @@ export default class Branches extends Component { {msg || '-'} - - - + + + + + ); diff --git a/blueocean-dashboard/src/main/js/components/StopPropagation.js b/blueocean-dashboard/src/main/js/components/StopPropagation.js new file mode 100644 index 00000000..308ee2c3 --- /dev/null +++ b/blueocean-dashboard/src/main/js/components/StopPropagation.js @@ -0,0 +1,40 @@ +/** + * Created by cmeyers on 7/27/16. + */ +import React, { Component, PropTypes } from 'react'; + +/** + * Stops propagation of click events inside this container. + * Useful for areas in UI where children should always handle the event, no matter what parent listeners are bound. + * + * This is a workaround for the following scenario: + * 1. Parent DOM element has a click listener, + * 2. Child DOM element added via an extension point calls event.stopPropagation() in its own click listener. + * + * This fails to work, even when calling stopProp and stopImmediateProp on the native event, + * probably beacuse there are two React trees each with their own document listener. + * + * see: http://stackoverflow.com/questions/24415631/reactjs-syntheticevent-stoppropagation-only-works-with-react-events + */ +export class StopPropagation extends Component { + + _suppressEvent(event) { + event.stopPropagation(); + } + + render() { + return ( +
this._suppressEvent(event)} + > + {this.props.children} +
+ ); + } +} + +StopPropagation.propTypes = { + children: PropTypes.node, + className: PropTypes.string, +};