diff --git a/client/coral-embed-stream/src/components/Stream.js b/client/coral-embed-stream/src/components/Stream.js index a547f10e8..5fde7c1df 100644 --- a/client/coral-embed-stream/src/components/Stream.js +++ b/client/coral-embed-stream/src/components/Stream.js @@ -75,7 +75,7 @@ class Stream extends React.Component { viewAllComments, auth: {loggedIn, user}, removeTag, - pluginConfig, + reduxState, editName } = this.props; const {keepCommentBox} = this.state; @@ -209,7 +209,7 @@ class Stream extends React.Component { - {getSlotComponents('streamTabs', pluginConfig, streamTabProps).map((PluginComponent) => ( + {getSlotComponents('streamTabs', reduxState, streamTabProps).map((PluginComponent) => ( - {getSlotComponents('streamTabPanes', pluginConfig, streamTabProps).map((PluginComponent) => ( + {getSlotComponents('streamTabPanes', reduxState, streamTabProps).map((PluginComponent) => ( ({ previousStreamTab: state.stream.previousTab, commentClassNames: state.stream.commentClassNames, pluginConfig: state.config.plugin_config, + reduxState: omit(state, 'apollo'), }); const mapDispatchToProps = (dispatch) => diff --git a/client/coral-framework/components/IfSlotIsEmpty.js b/client/coral-framework/components/IfSlotIsEmpty.js index b4dacf1eb..424a59bc7 100644 --- a/client/coral-framework/components/IfSlotIsEmpty.js +++ b/client/coral-framework/components/IfSlotIsEmpty.js @@ -2,11 +2,12 @@ import React from 'react'; import {connect} from 'react-redux'; import {isSlotEmpty} from 'coral-framework/helpers/plugins'; import PropTypes from 'prop-types'; +import omit from 'lodash/omit'; -function IfSlotIsEmpty({slot, className, pluginConfig, component: Component = 'div', children, ...rest}) { +function IfSlotIsEmpty({slot, className, reduxState, component: Component = 'div', children, ...rest}) { return ( - {isSlotEmpty(slot, pluginConfig, rest) ? children : null} + {isSlotEmpty(slot, reduxState, rest) ? children : null} ); } @@ -16,7 +17,9 @@ IfSlotIsEmpty.propTypes = { className: PropTypes.string, }; -const mapStateToProps = (state) => ({pluginConfig: state.config.plugin_config}); +const mapStateToProps = (state) => ({ + reduxState: omit(state, 'apollo'), +}); export default connect(mapStateToProps, null)(IfSlotIsEmpty); diff --git a/client/coral-framework/components/IfSlotIsNotEmpty.js b/client/coral-framework/components/IfSlotIsNotEmpty.js index 820a528fe..3a41fffbd 100644 --- a/client/coral-framework/components/IfSlotIsNotEmpty.js +++ b/client/coral-framework/components/IfSlotIsNotEmpty.js @@ -2,11 +2,12 @@ import React from 'react'; import {connect} from 'react-redux'; import {isSlotEmpty} from 'coral-framework/helpers/plugins'; import PropTypes from 'prop-types'; +import omit from 'lodash/omit'; -function IfSlotIsNotEmpty({slot, className, pluginConfig, component: Component = 'div', children, ...rest}) { +function IfSlotIsNotEmpty({slot, className, reduxState, component: Component = 'div', children, ...rest}) { return ( - {!isSlotEmpty(slot, pluginConfig, rest) ? children : null} + {!isSlotEmpty(slot, reduxState, rest) ? children : null} ); } @@ -16,7 +17,9 @@ IfSlotIsNotEmpty.propTypes = { className: PropTypes.string, }; -const mapStateToProps = (state) => ({pluginConfig: state.config.plugin_config}); +const mapStateToProps = (state) => ({ + reduxState: omit(state, 'apollo'), +}); export default connect(mapStateToProps, null)(IfSlotIsNotEmpty); diff --git a/client/coral-framework/components/Slot.js b/client/coral-framework/components/Slot.js index 2861a451c..b1df6647a 100644 --- a/client/coral-framework/components/Slot.js +++ b/client/coral-framework/components/Slot.js @@ -3,9 +3,11 @@ import cn from 'classnames'; import styles from './Slot.css'; import {connect} from 'react-redux'; import {getSlotElements} from 'coral-framework/helpers/plugins'; +import omit from 'lodash/omit'; -function Slot ({fill, inline = false, className, pluginConfig = {}, defaultComponent: DefaultComponent, ...rest}) { - let children = getSlotElements(fill, pluginConfig, rest); +function Slot ({fill, inline = false, className, reduxState, defaultComponent: DefaultComponent, ...rest}) { + let children = getSlotElements(fill, reduxState, rest); + const pluginConfig = reduxState.config.pluginConfig || {}; if (children.length === 0 && DefaultComponent) { children = ; } @@ -21,7 +23,9 @@ Slot.propTypes = { fill: React.PropTypes.string }; -const mapStateToProps = (state) => ({pluginConfig: state.config.plugin_config}); +const mapStateToProps = (state) => ({ + reduxState: omit(state, 'apollo'), +}); export default connect(mapStateToProps, null)(Slot); diff --git a/client/coral-framework/helpers/plugins.js b/client/coral-framework/helpers/plugins.js index 55fdaf6c5..2ec377050 100644 --- a/client/coral-framework/helpers/plugins.js +++ b/client/coral-framework/helpers/plugins.js @@ -10,7 +10,8 @@ import {loadTranslations} from 'coral-framework/services/i18n'; import {injectReducers} from 'coral-framework/services/store'; import camelize from './camelize'; -export function getSlotComponents(slot, pluginConfig, props = {}) { +export function getSlotComponents(slot, reduxState, props = {}) { + const pluginConfig = reduxState.config.pluginConfig || {}; return flatten(plugins // Filter out components that have slots and have been disabled in `plugin_config` @@ -19,18 +20,28 @@ export function getSlotComponents(slot, pluginConfig, props = {}) { .filter((o) => o.module.slots[slot]) .map((o) => o.module.slots[slot]) ) - .filter((component) => !component.isExcluded || !component.isExcluded({...props, config: pluginConfig})); + .filter((component) => { + if(!component.isExcluded) { + return true; + } + let resolvedProps = {...props, config: pluginConfig}; + if (component.mapStateToProps) { + resolvedProps = {...resolvedProps, ...component.mapStateToProps(reduxState)}; + } + return !component.isExcluded(resolvedProps); + }); } -export function isSlotEmpty(slot, pluginConfig, props) { - return getSlotComponents(slot, pluginConfig, props).length === 0; +export function isSlotEmpty(slot, reduxState, props) { + return getSlotComponents(slot, reduxState, props).length === 0; } /** * Returns React Elements for given slot. */ -export function getSlotElements(slot, pluginConfig, props = {}) { - return getSlotComponents(slot, pluginConfig, props) +export function getSlotElements(slot, reduxState, props = {}) { + const pluginConfig = reduxState.config.pluginConfig || {}; + return getSlotComponents(slot, reduxState, props) .map((component, i) => React.createElement(component, {key: i, ...props, config: pluginConfig})); } diff --git a/client/coral-framework/hocs/connect.js b/client/coral-framework/hocs/connect.js new file mode 100644 index 000000000..c49fe8380 --- /dev/null +++ b/client/coral-framework/hocs/connect.js @@ -0,0 +1,6 @@ +import {connect} from 'react-redux'; + +export default (mapStateToProps, ...rest) => (BaseComponent) => { + BaseComponent.mapStateToProps = mapStateToProps; + return connect(mapStateToProps, ...rest)(BaseComponent); +}; diff --git a/plugins/talk-plugin-featured/client/containers/Tab.js b/plugins/talk-plugin-featured/client/containers/Tab.js index f5d5678e6..2ca0ac4a2 100644 --- a/plugins/talk-plugin-featured/client/containers/Tab.js +++ b/plugins/talk-plugin-featured/client/containers/Tab.js @@ -1,10 +1,14 @@ import {compose, gql} from 'react-apollo'; import withFragments from 'coral-framework/hocs/withFragments'; import excludeIf from 'coral-framework/hocs/excludeIf'; +import connect from 'coral-framework/hocs/connect'; import Tab from '../components/Tab'; // TODO: This is just example code, and needs to replaced by an actual implementation. const enhance = compose( + connect((state) => ({ + stream: state.stream, + })), withFragments({ asset: gql` fragment TalkFeatured_Tab_asset on Asset { @@ -13,7 +17,9 @@ const enhance = compose( } }`, }), - excludeIf((props) => props.asset.recentComments.length === 0) + excludeIf((props) => { + return props.asset.recentComments.length === 0; + }) ); export default enhance(Tab);