From a22c3cf273bb1453cd3f4cfd6d9906d779596fde Mon Sep 17 00:00:00 2001 From: Ed Brett Date: Wed, 13 Jun 2018 16:04:34 +0200 Subject: [PATCH 1/3] add global disclaimer to footer of widgets --- app/javascript/components/widgets/actions.js | 26 ++++++++++++++++++- .../widget-settings-statement-selectors.js | 10 ++++--- .../widgets/components/widget/component.jsx | 3 +-- .../widgets/components/widget/selectors.js | 9 +++++++ .../widgets/components/widget/widget.js | 9 +++++-- app/javascript/components/widgets/reducers.js | 12 ++++++++- app/javascript/components/widgets/widgets.js | 22 +++++++++++++++- .../tree-loss-global/selectors.js | 8 +++++- app/javascript/services/forest-data.js | 7 ++++- 9 files changed, 94 insertions(+), 12 deletions(-) diff --git a/app/javascript/components/widgets/actions.js b/app/javascript/components/widgets/actions.js index 88198775f9..73a9e40cfb 100644 --- a/app/javascript/components/widgets/actions.js +++ b/app/javascript/components/widgets/actions.js @@ -2,7 +2,9 @@ import { createAction } from 'redux-actions'; import { createThunkAction } from 'utils/redux'; import isEqual from 'lodash/isEqual'; import pick from 'lodash/pick'; +import groupBy from 'lodash/groupBy'; import { encodeStateForUrl, decodeUrlForState } from 'utils/stateToUrl'; +import { getNonGlobalDatasets } from 'services/forest-data'; import { COUNTRY, EMBED } from 'pages/dashboards/router'; import * as WIDGETS from './manifest'; @@ -10,6 +12,7 @@ export const setWidgetSettings = createAction('setWidgetSettings'); export const setWidgetLoading = createAction('setWidgetLoading'); export const setWidgetData = createAction('setWidgetData'); export const settingsItemSelected = createAction('settingsItemSelected'); +export const setGlobalData = createAction('setGlobalData'); export const getWidgetData = createThunkAction( 'getWidgetData', @@ -72,12 +75,33 @@ export const setWidgetSettingsStore = createThunkAction( } ); +export const getGlobalData = createThunkAction( + 'getGlobalData', + () => dispatch => { + getNonGlobalDatasets().then(response => { + const { data } = response.data; + const groupedData = groupBy(data, 'polyname'); + const nonGlobalDatasets = {}; + Object.keys(groupedData).forEach(d => { + nonGlobalDatasets[d] = groupedData[d].length; + }); + dispatch( + setGlobalData({ + nonGlobalDatasets + }) + ); + }); + } +); + export default { setWidgetSettingsUrl, setWidgetSettingsStore, settingsItemSelected, setWidgetData, getWidgetData, + getGlobalData, setWidgetLoading, - setWidgetSettings + setWidgetSettings, + setGlobalData }; diff --git a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js b/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js index 143989204f..cccc27f924 100644 --- a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js +++ b/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js @@ -3,12 +3,13 @@ import compact from 'lodash/compact'; // get list data const getSettings = state => state.settings || null; -const getType = state => state.type || null; +const getType = state => state.config.type || null; +const getNonGlobalDatasets = state => state.nonGlobalDatasets || null; // get lists selected export const getStatement = createSelector( - [getSettings, getType], - (settings, type) => { + [getSettings, getType, getNonGlobalDatasets], + (settings, type, datasets) => { if (!settings) return ''; const { extentYear, threshold } = settings; const statements = compact([ @@ -16,6 +17,9 @@ export const getStatement = createSelector( threshold || threshold === 0 ? `>${threshold}% tree canopy` : null, type === 'loss' ? 'these estimates do not take tree cover gain into account' + : null, + datasets + ? `* this dataset is available in ${datasets} countries only` : null ]); diff --git a/app/javascript/components/widgets/components/widget/component.jsx b/app/javascript/components/widgets/components/widget/component.jsx index eccb594c03..2b98df7cbf 100644 --- a/app/javascript/components/widgets/components/widget/component.jsx +++ b/app/javascript/components/widgets/components/widget/component.jsx @@ -18,7 +18,6 @@ class Widget extends PureComponent { widget, currentLabel, shareUrl, - settings, config, embed, loading, @@ -80,7 +79,7 @@ class Widget extends PureComponent { /> )} - + {embed && (!query || (query && !query.hideGfw)) && (
diff --git a/app/javascript/components/widgets/components/widget/selectors.js b/app/javascript/components/widgets/components/widget/selectors.js index fdcae27036..ad904569be 100644 --- a/app/javascript/components/widgets/components/widget/selectors.js +++ b/app/javascript/components/widgets/components/widget/selectors.js @@ -15,6 +15,7 @@ const getLocation = state => state.payload || null; const getWhitelist = state => state.whitelist || null; const getForestType = state => state.forestType || null; const getLandCategory = state => state.landCategory || null; +const getDatasets = state => state.nonGlobalDatasets || null; export const getOptionsSelected = createSelector( [getOptions, getSettings], @@ -57,6 +58,14 @@ export const getIndicator = createSelector( } ); +export const getNonGlobalDatasets = createSelector( + [getIndicator, getLocation, getDatasets], + (indicator, location, datasets) => { + if (!datasets || location.type !== 'global') return null; + return datasets[indicator && indicator.value]; + } +); + // get options export const getForestTypes = createSelector( [getWhitelist, getLocation, getConfig, getOptions], diff --git a/app/javascript/components/widgets/components/widget/widget.js b/app/javascript/components/widgets/components/widget/widget.js index 9ac016f348..1aa18f4526 100644 --- a/app/javascript/components/widgets/components/widget/widget.js +++ b/app/javascript/components/widgets/components/widget/widget.js @@ -16,7 +16,7 @@ const mapStateToProps = ({ widgets, location }, ownProps) => { const { country, region, subRegion, type } = location.payload; // widget consts const { config, settings } = widgets[widget]; - const { getOptionsSelected, getIndicator } = Selectors; + const { getOptionsSelected, getIndicator, getNonGlobalDatasets } = Selectors; const highlightColor = colors.main || '#a0c746'; const haveMapLayers = settings && !isEmpty(settings.layers); const onMap = active && haveMapLayers; @@ -40,6 +40,10 @@ const mapStateToProps = ({ widgets, location }, ownProps) => { : options[selector]; }); } + const nonGlobalDatasets = getNonGlobalDatasets({ + ...widgets.global, + ...selectorData + }); const category = query && query.category; const locationUrl = `${country || ''}${region ? `/${region}` : ''}${ @@ -69,7 +73,8 @@ const mapStateToProps = ({ widgets, location }, ownProps) => { parsedConfig: parseConfig && parseConfig(selectorData), sentence: getSentence && getSentence(selectorData), shareUrl, - embedUrl + embedUrl, + nonGlobalDatasets }; }; diff --git a/app/javascript/components/widgets/reducers.js b/app/javascript/components/widgets/reducers.js index c7aca2930d..62943c7ea2 100644 --- a/app/javascript/components/widgets/reducers.js +++ b/app/javascript/components/widgets/reducers.js @@ -12,9 +12,18 @@ Object.keys(Widgets).forEach(key => { }); export const initialState = { + global: {}, ...widgets }; +const setGlobalData = (state, { payload }) => ({ + ...state, + global: { + ...state.global, + ...payload + } +}); + const setWidgetLoading = (state, { payload }) => ({ ...state, [payload]: { @@ -62,5 +71,6 @@ export default { setWidgetSettings, setWidgetLoading, setWidgetData, - setWidgetActive + setWidgetActive, + setGlobalData }; diff --git a/app/javascript/components/widgets/widgets.js b/app/javascript/components/widgets/widgets.js index 8d1b5e21ad..8652eb50be 100644 --- a/app/javascript/components/widgets/widgets.js +++ b/app/javascript/components/widgets/widgets.js @@ -1,4 +1,7 @@ +import { createElement, PureComponent } from 'react'; import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; + import colors from 'data/colors.json'; import Component from './component'; @@ -64,6 +67,23 @@ const mapStateToProps = ( }; }; +class WidgetsContainer extends PureComponent { + componentDidMount() { + const { getGlobalData } = this.props; + getGlobalData(); + } + + render() { + return createElement(Component, { + ...this.props + }); + } +} + +WidgetsContainer.propTypes = { + getGlobalData: PropTypes.func +}; + export { actions, reducers, initialState }; -export default connect(mapStateToProps, actions)(Component); +export default connect(mapStateToProps, actions)(WidgetsContainer); diff --git a/app/javascript/components/widgets/widgets/forest-change/tree-loss-global/selectors.js b/app/javascript/components/widgets/widgets/forest-change/tree-loss-global/selectors.js index fb1acf6fee..39741c2184 100644 --- a/app/javascript/components/widgets/widgets/forest-change/tree-loss-global/selectors.js +++ b/app/javascript/components/widgets/widgets/forest-change/tree-loss-global/selectors.js @@ -162,7 +162,13 @@ export const getSentence = createSelector( const params = { indicator: indicator && indicator.label.toLowerCase(), - location: currentLabel === 'global' ? 'globally' : currentLabel, + location: + currentLabel === 'global' + ? { + value: 'globally', + tooltip: 'this dataset is available in certain countries' + } + : currentLabel, startYear, endYear, loss: diff --git a/app/javascript/services/forest-data.js b/app/javascript/services/forest-data.js index 6efc2fa70a..4db82aa836 100644 --- a/app/javascript/services/forest-data.js +++ b/app/javascript/services/forest-data.js @@ -37,7 +37,9 @@ const SQL_QUERIES = { faoDeforestRank: 'WITH mytable AS (SELECT fao.country as iso, fao.name, fao.deforest * 1000 AS deforest, fao.humdef FROM table_1_forest_area_and_characteristics as fao WHERE fao.year = {year} AND deforest is not null), rank AS (SELECT deforest, iso, name from mytable ORDER BY mytable.deforest DESC) SELECT row_number() over () as rank, iso, name, deforest from rank', faoEcoLive: - 'SELECT fao.country, fao.forempl, fao.femempl, fao.usdrev, fao.usdexp, fao.gdpusd2012, fao.totpop1000, fao.year FROM table_7_economics_livelihood as fao WHERE fao.year = 2000 or fao.year = 2005 or fao.year = 2010 or fao.year = 9999' + 'SELECT fao.country, fao.forempl, fao.femempl, fao.usdrev, fao.usdexp, fao.gdpusd2012, fao.totpop1000, fao.year FROM table_7_economics_livelihood as fao WHERE fao.year = 2000 or fao.year = 2005 or fao.year = 2010 or fao.year = 9999', + nonGlobalDatasets: + "SELECT iso, polyname FROM data WHERE polyname IN ('plantations', 'mining', 'primary_forest', 'landmark', 'plantations__mining', 'plantations__landmark', 'primary_forest__mining', 'primary_forest__landmark') GROUP BY iso, polyname ORDER BY polyname, iso" }; const getExtentYear = year => @@ -277,3 +279,6 @@ export const getGainRanked = ({ .replace('{polyname}', getIndicator(forestType, landCategory)); return request.get(url); }; + +export const getNonGlobalDatasets = () => + request.get(`${REQUEST_URL}${SQL_QUERIES.nonGlobalDatasets}`); From 88b1aaf70aee05b91e1d62ece5b5a8769f62d8af Mon Sep 17 00:00:00 2001 From: Ed Brett Date: Wed, 13 Jun 2018 16:31:18 +0200 Subject: [PATCH 2/3] show sentence when intersection selected --- .../widget-settings-statement-selectors.js | 2 +- .../widgets/components/widget/selectors.js | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js b/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js index cccc27f924..367931909b 100644 --- a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js +++ b/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js @@ -19,7 +19,7 @@ export const getStatement = createSelector( ? 'these estimates do not take tree cover gain into account' : null, datasets - ? `* this dataset is available in ${datasets} countries only` + ? `*this dataset is available in ${datasets} countries only` : null ]); diff --git a/app/javascript/components/widgets/components/widget/selectors.js b/app/javascript/components/widgets/components/widget/selectors.js index ad904569be..cf32b58505 100644 --- a/app/javascript/components/widgets/components/widget/selectors.js +++ b/app/javascript/components/widgets/components/widget/selectors.js @@ -15,7 +15,7 @@ const getLocation = state => state.payload || null; const getWhitelist = state => state.whitelist || null; const getForestType = state => state.forestType || null; const getLandCategory = state => state.landCategory || null; -const getDatasets = state => state.nonGlobalDatasets || null; +const getGlobalDatasets = state => state.nonGlobalDatasets || null; export const getOptionsSelected = createSelector( [getOptions, getSettings], @@ -59,10 +59,20 @@ export const getIndicator = createSelector( ); export const getNonGlobalDatasets = createSelector( - [getIndicator, getLocation, getDatasets], - (indicator, location, datasets) => { + [ + getIndicator, + getForestType, + getLandCategory, + getLocation, + getGlobalDatasets + ], + (indicator, forestType, landCategory, location, datasets) => { if (!datasets || location.type !== 'global') return null; - return datasets[indicator && indicator.value]; + return ( + datasets[indicator && indicator.value] || + datasets[forestType && forestType.value] || + datasets[landCategory && landCategory.value] + ); } ); From f3a39021e4155327c654f2f90d8d0e41c5053dfc Mon Sep 17 00:00:00 2001 From: Ed Brett Date: Wed, 13 Jun 2018 19:35:16 +0200 Subject: [PATCH 3/3] add indicator label to footer, update selector to footer component --- .../components/widget-footer/component.jsx | 20 +++++++ .../components/widget-footer/selectors.js | 55 +++++++++++++++++++ .../styles.scss} | 2 +- .../widget-footer.js} | 4 +- .../widget-settings-statement-component.jsx | 20 ------- .../widget-settings-statement-selectors.js | 28 ---------- .../widgets/components/widget/component.jsx | 4 +- .../widgets/components/widget/selectors.js | 19 ------- .../widgets/components/widget/widget.js | 8 +-- 9 files changed, 82 insertions(+), 78 deletions(-) create mode 100644 app/javascript/components/widgets/components/widget-footer/component.jsx create mode 100644 app/javascript/components/widgets/components/widget-footer/selectors.js rename app/javascript/components/widgets/components/{widget-settings-statement/widget-settings-statement-styles.scss => widget-footer/styles.scss} (77%) rename app/javascript/components/widgets/components/{widget-settings-statement/widget-settings-statement.js => widget-footer/widget-footer.js} (57%) delete mode 100644 app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-component.jsx delete mode 100644 app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js diff --git a/app/javascript/components/widgets/components/widget-footer/component.jsx b/app/javascript/components/widgets/components/widget-footer/component.jsx new file mode 100644 index 0000000000..861225b1e5 --- /dev/null +++ b/app/javascript/components/widgets/components/widget-footer/component.jsx @@ -0,0 +1,20 @@ +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; + +import './styles.scss'; + +class WidgetFooter extends PureComponent { + render() { + const { statement } = this.props; + + return statement ? ( +
{statement}
+ ) : null; + } +} + +WidgetFooter.propTypes = { + statement: PropTypes.string +}; + +export default WidgetFooter; diff --git a/app/javascript/components/widgets/components/widget-footer/selectors.js b/app/javascript/components/widgets/components/widget-footer/selectors.js new file mode 100644 index 0000000000..5aed875cff --- /dev/null +++ b/app/javascript/components/widgets/components/widget-footer/selectors.js @@ -0,0 +1,55 @@ +import { createSelector } from 'reselect'; +import compact from 'lodash/compact'; + +// get list data +const getSettings = state => state.settings || null; +const getType = state => state.config.type || null; +const getNonGlobalDatasets = state => state.nonGlobalDatasets || null; +const getIndicator = state => state.indicator || null; +const getForestType = state => state.forestType || null; +const getLandCategory = state => state.landCategory || null; +const getLocation = state => state.payload || null; + +export const getNonGlobalIndicator = createSelector( + [ + getIndicator, + getForestType, + getLandCategory, + getLocation, + getNonGlobalDatasets + ], + (indicator, forestType, landCategory, location, datasets) => { + if (!datasets || location.type !== 'global' || !indicator) return null; + if (datasets[indicator.value]) { + return indicator; + } else if (datasets[forestType && forestType.value]) { + return forestType; + } else if (datasets[landCategory && landCategory.value]) { + return landCategory; + } + return null; + } +); + +// get lists selected +export const getStatement = createSelector( + [getSettings, getType, getNonGlobalDatasets, getNonGlobalIndicator], + (settings, type, datasets, indicator) => { + if (!settings) return ''; + const { extentYear, threshold } = settings; + const statements = compact([ + extentYear ? `${extentYear} tree cover extent` : null, + threshold || threshold === 0 ? `>${threshold}% tree canopy` : null, + type === 'loss' + ? 'these estimates do not take tree cover gain into account' + : null, + datasets && indicator + ? `*${indicator.label.toLowerCase()} are available in ${ + datasets[indicator.value] + } countries only` + : null + ]); + + return statements.join(' | '); + } +); diff --git a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-styles.scss b/app/javascript/components/widgets/components/widget-footer/styles.scss similarity index 77% rename from app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-styles.scss rename to app/javascript/components/widgets/components/widget-footer/styles.scss index 25d5a0977d..54c5b72c20 100644 --- a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-styles.scss +++ b/app/javascript/components/widgets/components/widget-footer/styles.scss @@ -1,6 +1,6 @@ @import '~styles/settings.scss'; -.c-widget-settings-statement { +.c-widget-footer { margin-top: rem(10px); font-size: 12px; color: rgba($slate, 0.5); diff --git a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement.js b/app/javascript/components/widgets/components/widget-footer/widget-footer.js similarity index 57% rename from app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement.js rename to app/javascript/components/widgets/components/widget-footer/widget-footer.js index c7281792d7..077a322d0d 100644 --- a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement.js +++ b/app/javascript/components/widgets/components/widget-footer/widget-footer.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; -import { getStatement } from './widget-settings-statement-selectors'; -import Component from './widget-settings-statement-component'; +import { getStatement } from './selectors'; +import Component from './component'; const mapStateToProps = (state, ownProps) => ({ statement: getStatement(ownProps) diff --git a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-component.jsx b/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-component.jsx deleted file mode 100644 index 289f0040fc..0000000000 --- a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-component.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; - -import './widget-settings-statement-styles.scss'; - -class WidgetSettingsStatement extends PureComponent { - render() { - const { statement } = this.props; - - return statement ? ( -
{statement}
- ) : null; - } -} - -WidgetSettingsStatement.propTypes = { - statement: PropTypes.string -}; - -export default WidgetSettingsStatement; diff --git a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js b/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js deleted file mode 100644 index 367931909b..0000000000 --- a/app/javascript/components/widgets/components/widget-settings-statement/widget-settings-statement-selectors.js +++ /dev/null @@ -1,28 +0,0 @@ -import { createSelector } from 'reselect'; -import compact from 'lodash/compact'; - -// get list data -const getSettings = state => state.settings || null; -const getType = state => state.config.type || null; -const getNonGlobalDatasets = state => state.nonGlobalDatasets || null; - -// get lists selected -export const getStatement = createSelector( - [getSettings, getType, getNonGlobalDatasets], - (settings, type, datasets) => { - if (!settings) return ''; - const { extentYear, threshold } = settings; - const statements = compact([ - extentYear ? `${extentYear} tree cover extent` : null, - threshold || threshold === 0 ? `>${threshold}% tree canopy` : null, - type === 'loss' - ? 'these estimates do not take tree cover gain into account' - : null, - datasets - ? `*this dataset is available in ${datasets} countries only` - : null - ]); - - return statements.join(' | '); - } -); diff --git a/app/javascript/components/widgets/components/widget/component.jsx b/app/javascript/components/widgets/components/widget/component.jsx index 2b98df7cbf..24fe942485 100644 --- a/app/javascript/components/widgets/components/widget/component.jsx +++ b/app/javascript/components/widgets/components/widget/component.jsx @@ -8,7 +8,7 @@ import Button from 'components/ui/button'; import DynamicSentence from 'components/ui/dynamic-sentence'; import WidgetHeader from '../widget-header'; -import WidgetSettingsStatement from '../widget-settings-statement'; +import WidgetFooter from '../widget-footer'; import './styles.scss'; @@ -79,7 +79,7 @@ class Widget extends PureComponent { /> )}
- + {embed && (!query || (query && !query.hideGfw)) && (
diff --git a/app/javascript/components/widgets/components/widget/selectors.js b/app/javascript/components/widgets/components/widget/selectors.js index cf32b58505..fdcae27036 100644 --- a/app/javascript/components/widgets/components/widget/selectors.js +++ b/app/javascript/components/widgets/components/widget/selectors.js @@ -15,7 +15,6 @@ const getLocation = state => state.payload || null; const getWhitelist = state => state.whitelist || null; const getForestType = state => state.forestType || null; const getLandCategory = state => state.landCategory || null; -const getGlobalDatasets = state => state.nonGlobalDatasets || null; export const getOptionsSelected = createSelector( [getOptions, getSettings], @@ -58,24 +57,6 @@ export const getIndicator = createSelector( } ); -export const getNonGlobalDatasets = createSelector( - [ - getIndicator, - getForestType, - getLandCategory, - getLocation, - getGlobalDatasets - ], - (indicator, forestType, landCategory, location, datasets) => { - if (!datasets || location.type !== 'global') return null; - return ( - datasets[indicator && indicator.value] || - datasets[forestType && forestType.value] || - datasets[landCategory && landCategory.value] - ); - } -); - // get options export const getForestTypes = createSelector( [getWhitelist, getLocation, getConfig, getOptions], diff --git a/app/javascript/components/widgets/components/widget/widget.js b/app/javascript/components/widgets/components/widget/widget.js index 1aa18f4526..3130ead33f 100644 --- a/app/javascript/components/widgets/components/widget/widget.js +++ b/app/javascript/components/widgets/components/widget/widget.js @@ -16,7 +16,7 @@ const mapStateToProps = ({ widgets, location }, ownProps) => { const { country, region, subRegion, type } = location.payload; // widget consts const { config, settings } = widgets[widget]; - const { getOptionsSelected, getIndicator, getNonGlobalDatasets } = Selectors; + const { getOptionsSelected, getIndicator } = Selectors; const highlightColor = colors.main || '#a0c746'; const haveMapLayers = settings && !isEmpty(settings.layers); const onMap = active && haveMapLayers; @@ -40,10 +40,6 @@ const mapStateToProps = ({ widgets, location }, ownProps) => { : options[selector]; }); } - const nonGlobalDatasets = getNonGlobalDatasets({ - ...widgets.global, - ...selectorData - }); const category = query && query.category; const locationUrl = `${country || ''}${region ? `/${region}` : ''}${ @@ -74,7 +70,7 @@ const mapStateToProps = ({ widgets, location }, ownProps) => { sentence: getSentence && getSentence(selectorData), shareUrl, embedUrl, - nonGlobalDatasets + ...widgets.global }; };