From c57707d2dd257744e905e1ea3573443caf2ada6c Mon Sep 17 00:00:00 2001 From: Bohdan Iakymets Date: Mon, 18 Feb 2019 15:09:42 +0100 Subject: [PATCH] feat(VncConsole): More possibilities to customize component, like: extraction toolbar and console sc Added possibility to extract toolbar to any other component. Added scaling prop to VncConsole, and enhance `textConnecting` props to use node type as well. And fixed disconnecting. --- .../src/VncConsole/VncActions.js | 47 +++++++++-- .../src/VncConsole/VncConsole.js | 58 +++++++++---- .../__snapshots__/VncActions.test.js.snap | 84 ++++++++++++------- .../__snapshots__/VncConsole.test.js.snap | 26 +++--- 4 files changed, 149 insertions(+), 66 deletions(-) diff --git a/packages/patternfly-3/react-console/src/VncConsole/VncActions.js b/packages/patternfly-3/react-console/src/VncConsole/VncActions.js index f036c2eff5b..787aaf28227 100644 --- a/packages/patternfly-3/react-console/src/VncConsole/VncActions.js +++ b/packages/patternfly-3/react-console/src/VncConsole/VncActions.js @@ -1,30 +1,59 @@ import React from 'react'; +import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import { MenuItem, Button, helpers } from 'patternfly-react'; const { Dropdown } = Button; const { noop } = helpers; -const VncActions = ({ textSendShortcut, textCtrlAltDel, onCtrlAltDel }) => ( - - - {textCtrlAltDel} - - -); +const VncActions = ({ + textSendShortcut, + textCtrlAltDel, + textDisconnect, + onCtrlAltDel, + onDisconnect, + insertToolbarTo +}) => { + const toolbar = ( +
+ + + {textCtrlAltDel} + + + +
+ ); + + if (!insertToolbarTo) { + return toolbar; + } + return ( + document.getElementById(insertToolbarTo) && ReactDOM.createPortal(toolbar, document.getElementById(insertToolbarTo)) + ); +}; VncActions.propTypes = { + onDisconnect: PropTypes.func.isRequired, onCtrlAltDel: PropTypes.func, textCtrlAltDel: PropTypes.string, - textSendShortcut: PropTypes.string + textSendShortcut: PropTypes.string, + textDisconnect: PropTypes.string, + + insertToolbarTo: PropTypes.string // id of element where VncAction should be inserted }; VncActions.defaultProps = { onCtrlAltDel: noop, textCtrlAltDel: 'Ctrl+Alt+Del', - textSendShortcut: 'Send Key' + textSendShortcut: 'Send Key', + textDisconnect: 'Disconnect', + + insertToolbarTo: '' }; export default VncActions; diff --git a/packages/patternfly-3/react-console/src/VncConsole/VncConsole.js b/packages/patternfly-3/react-console/src/VncConsole/VncConsole.js index c36edd438f4..f4c0d9ff083 100644 --- a/packages/patternfly-3/react-console/src/VncConsole/VncConsole.js +++ b/packages/patternfly-3/react-console/src/VncConsole/VncConsole.js @@ -31,6 +31,7 @@ class VncConsole extends React.Component { path, encrypt, resizeSession, + scaleViewport, viewOnly, shared, credentials, @@ -53,7 +54,7 @@ class VncConsole extends React.Component { this.rfb = new RFB(this.novncElem, url, options); this.addEventListeners(); this.rfb.viewOnly = viewOnly; - this.rfb.scaleViewport = false; // if the remote session is smaller than HTML container, the view will be centered + this.rfb.scaleViewport = scaleViewport; this.rfb.resizeSession = resizeSession; } catch (e) { onInitFailed && onInitFailed(e); @@ -62,17 +63,17 @@ class VncConsole extends React.Component { } componentWillUnmount() { - this.removeEventListeners(); this.disconnect(); + this.removeEventListeners(); + this.rfb = undefined; } - disconnect() { + disconnect = () => { if (!this.rfb) { return; } this.rfb.disconnect(); - this.rfb = undefined; - } + }; onConnected = () => { this.setState({ status: CONNECTED }); @@ -95,11 +96,11 @@ class VncConsole extends React.Component { this.props.onSecurityFailure(e); }; - removeEventListeners() { + removeEventListeners = () => { this.rfb.removeEventListener('connect', this.onConnected); this.rfb.removeEventListener('disconnect', this.onDisconnected); this.rfb.removeEventListener('securityfailure', this.onSecurityFailure); - } + }; setNovncElem = e => { this.novncElem = e; @@ -113,7 +114,14 @@ class VncConsole extends React.Component { }; render() { - const { textDisconnected, textConnecting, textSendShortcut, textCtrlAltDel } = this.props; + const { + textDisconnected, + textConnecting, + textSendShortcut, + textCtrlAltDel, + textDisconnect, + portalToolbarTo + } = this.props; let status = null; let rightContent = null; @@ -121,9 +129,12 @@ class VncConsole extends React.Component { case CONNECTED: rightContent = ( ); break; @@ -143,11 +154,21 @@ class VncConsole extends React.Component { return (
{this.props.children} - {rightContent} - - {status} - {this.novncStaticComponent} - + {portalToolbarTo ? ( + + {rightContent} + {status} + {this.novncStaticComponent} + + ) : ( + + {rightContent} + + {status} + {this.novncStaticComponent} + + + )}
); } @@ -163,11 +184,13 @@ VncConsole.propTypes = { path: PropTypes.string /** host:port/path */, encrypt: PropTypes.bool /** For all following, see: https://github.com/novnc/noVNC/blob/master/docs/API.md */, resizeSession: PropTypes.bool /** Change remote session size according to local HTML container */, + scaleViewport: PropTypes.bool /** Scale session size according to parent HTML container */, viewOnly: PropTypes.bool, shared: PropTypes.bool, credentials: PropTypes.object /** { username: '', password: '', target: ''} */, repeaterID: PropTypes.string, vncLogging: PropTypes.string /** log-level for noVNC */, + portalToolbarTo: PropTypes.string, topClassName: PropTypes.string /** Enable customization */, @@ -175,8 +198,12 @@ VncConsole.propTypes = { onInitFailed: PropTypes.func /** Initialization of RFB failed */, onSecurityFailure: PropTypes.func /** Handshake failed */, - textConnecting: PropTypes.string /** For localization */, + textConnecting: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.node + ]) /** For localization and better integration */, textDisconnected: PropTypes.string, + textDisconnect: PropTypes.string, textSendShortcut: PropTypes.string, textCtrlAltDel: PropTypes.string }; @@ -188,11 +215,13 @@ VncConsole.defaultProps = { path: '', encrypt: false, resizeSession: true, + scaleViewport: false, viewOnly: false, shared: false, credentials: undefined, repeaterID: '', vncLogging: 'warn', + portalToolbarTo: '', topClassName: '', @@ -202,6 +231,7 @@ VncConsole.defaultProps = { textConnecting: 'Connecting', textDisconnected: 'Disconnected', + textDisconnect: 'Disconnect', textSendShortcut: undefined /** Default value defined in VncActions */, textCtrlAltDel: undefined /** Default value defined in VncActions */ }; diff --git a/packages/patternfly-3/react-console/src/VncConsole/__snapshots__/VncActions.test.js.snap b/packages/patternfly-3/react-console/src/VncConsole/__snapshots__/VncActions.test.js.snap index d81d4711dba..61715b9114e 100644 --- a/packages/patternfly-3/react-console/src/VncConsole/__snapshots__/VncActions.test.js.snap +++ b/packages/patternfly-3/react-console/src/VncConsole/__snapshots__/VncActions.test.js.snap @@ -1,43 +1,65 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`VncActions renders correctly component hierarchy 1`] = ` - - + + + foobar + + + + `; -exports[`VncActions renders correctly html 1`] = `"
"`; +exports[`VncActions renders correctly html 1`] = `"
"`; exports[`placeholder render test 1`] = ` - - + + + Ctrl+Alt+Del + + + + `; diff --git a/packages/patternfly-3/react-console/src/VncConsole/__snapshots__/VncConsole.test.js.snap b/packages/patternfly-3/react-console/src/VncConsole/__snapshots__/VncConsole.test.js.snap index 2667831739e..5ec2429552e 100644 --- a/packages/patternfly-3/react-console/src/VncConsole/__snapshots__/VncConsole.test.js.snap +++ b/packages/patternfly-3/react-console/src/VncConsole/__snapshots__/VncConsole.test.js.snap @@ -4,18 +4,20 @@ exports[`placeholder render test 1`] = `
- - -
+ + - Connecting -
-
- +
+ Connecting +
+
+ +
`;