Commit 6f7603fe authored by Joram Wilander's avatar Joram Wilander Committed by GitHub

PLT-7545 Add plugin support for a root component (#86)

* Add plugin support for a root component

* Update overrideName to pluggableName
parent a69bedc3
import PropTypes from 'prop-types';
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import PropTypes from 'prop-types';
import Pluggable from 'plugins/pluggable';
import TeamStore from 'stores/team_store.jsx';
import UserStore from 'stores/user_store.jsx';
......@@ -57,6 +58,7 @@ export default class BackstageController extends React.Component {
<div className='backstage'>
<AnnouncementBar/>
<BackstageNavbar team={this.state.team}/>
<Pluggable pluggableName='Root'/>
<div className='backstage-body'>
<BackstageSidebar
team={this.state.team}
......
......@@ -29,6 +29,8 @@ import WebrtcSidebar from 'components/webrtc/components/webrtc_sidebar.jsx';
import WebrtcNotification from 'components/webrtc/components/webrtc_notification.jsx';
import Pluggable from 'plugins/pluggable';
import store from 'stores/redux_store.jsx';
import {getPost} from 'mattermost-redux/selectors/entities/posts';
......@@ -221,6 +223,7 @@ export default class NeedsTeam extends React.Component {
<WebrtcSidebar/>
{content}
<Pluggable pluggableName='Root'/>
<UserSettingsModal/>
<GetPostLinkModal/>
<GetPublicLinkModal/>
......
......@@ -10,9 +10,14 @@ export default class Pluggable extends React.PureComponent {
static propTypes = {
/*
* Should be a single overridable React component
* Should be a single overridable React component. One of this or pluggableName is required
*/
children: PropTypes.element.isRequired,
children: PropTypes.element,
/*
* Override the component to be plugged. One of this or children is required
*/
pluggableName: PropTypes.string,
/*
* Components for overriding provided by plugins
......@@ -26,24 +31,29 @@ export default class Pluggable extends React.PureComponent {
}
render() {
const child = React.Children.only(this.props.children).type;
const components = this.props.components;
const pluggableName = this.props.pluggableName;
if (child == null) {
let child;
if (this.props.children) {
child = React.Children.only(this.props.children).type;
} else if (!pluggableName) {
return null;
}
const childName = child.getComponentName();
const components = this.props.components;
const childrenProps = child ? this.props.children.props : {};
const componentName = pluggableName || child.getComponentName();
// Include any props passed to this component or to the child component
let props = {...this.props};
Reflect.deleteProperty(props, 'children');
Reflect.deleteProperty(props, 'components');
props = {...props, ...this.props.children.props};
Reflect.deleteProperty(props, 'pluggableName');
props = {...props, ...childrenProps};
// Override the default component with any registered plugin's component
if (components.hasOwnProperty(childName)) {
const PluginComponent = components[childName].component;
if (components.hasOwnProperty(componentName)) {
const PluginComponent = components[componentName].component;
return (
<PluginComponent
{...props}
......@@ -52,6 +62,10 @@ export default class Pluggable extends React.PureComponent {
);
}
if (child == null) {
return null;
}
return React.cloneElement(this.props.children, {...props});
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment