From 59268e978aa2753166371f790fa648ddaa398f52 Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Wed, 16 Aug 2017 23:00:23 -0700 Subject: [PATCH] Use react-alert for backend message flashing (#3315) --- .../javascripts/SqlLab/components/App.jsx | 4 +++- .../javascripts/components/AlertsWrapper.jsx | 20 +++++++++++++++++++ .../javascripts/dashboard/Dashboard.jsx | 8 ++++++-- superset/assets/javascripts/explore/index.jsx | 3 +-- superset/templates/superset/basic.html | 1 - superset/templates/superset/dashboard.html | 2 -- superset/views/base.py | 12 ++++++++++- superset/views/core.py | 6 +++++- 8 files changed, 46 insertions(+), 10 deletions(-) diff --git a/superset/assets/javascripts/SqlLab/components/App.jsx b/superset/assets/javascripts/SqlLab/components/App.jsx index 2a6eb4186406c..2d45281634bd4 100644 --- a/superset/assets/javascripts/SqlLab/components/App.jsx +++ b/superset/assets/javascripts/SqlLab/components/App.jsx @@ -70,7 +70,7 @@ class App extends React.PureComponent { } return (
- +
{content}
@@ -82,11 +82,13 @@ class App extends React.PureComponent { App.propTypes = { alerts: PropTypes.array, actions: PropTypes.object, + initMessages: PropTypes.array, }; function mapStateToProps(state) { return { alerts: state.alerts, + initMessages: state.flash_messages, }; } function mapDispatchToProps(dispatch) { diff --git a/superset/assets/javascripts/components/AlertsWrapper.jsx b/superset/assets/javascripts/components/AlertsWrapper.jsx index bb3c2d6dc8398..672c56d59d830 100644 --- a/superset/assets/javascripts/components/AlertsWrapper.jsx +++ b/superset/assets/javascripts/components/AlertsWrapper.jsx @@ -1,7 +1,25 @@ +/* global notify */ import React from 'react'; import AlertContainer from 'react-alert'; +import PropTypes from 'prop-types'; + +const propTypes = { + initMessages: PropTypes.array, +}; +const defaultProps = { + initMessages: [], +}; export default class AlertsWrapper extends React.PureComponent { + componentDidMount() { + this.props.initMessages.forEach((msg) => { + if (['info', 'error', 'success'].indexOf(msg[0]) >= 0) { + notify[msg[0]](msg[1]); + } else { + notify.show(msg[1]); + } + }); + } render() { return ( ); } } +AlertsWrapper.propTypes = propTypes; +AlertsWrapper.defaultProps = defaultProps; diff --git a/superset/assets/javascripts/dashboard/Dashboard.jsx b/superset/assets/javascripts/dashboard/Dashboard.jsx index 283475acfe85a..7cc7699c44785 100644 --- a/superset/assets/javascripts/dashboard/Dashboard.jsx +++ b/superset/assets/javascripts/dashboard/Dashboard.jsx @@ -18,7 +18,11 @@ const utils = require('../modules/utils'); appSetup(); export function getInitialState(boostrapData) { - const dashboard = Object.assign({}, utils.controllerInterface, boostrapData.dashboard_data); + const dashboard = Object.assign( + {}, + utils.controllerInterface, + boostrapData.dashboard_data, + { common: boostrapData.common }); dashboard.firstLoad = true; dashboard.posDict = {}; @@ -62,7 +66,7 @@ function renderAlert() { function initDashboardView(dashboard) { render(
- +
, document.getElementById('dashboard-header'), diff --git a/superset/assets/javascripts/explore/index.jsx b/superset/assets/javascripts/explore/index.jsx index 525f2c4fe30d1..501002afccd4c 100644 --- a/superset/assets/javascripts/explore/index.jsx +++ b/superset/assets/javascripts/explore/index.jsx @@ -56,12 +56,11 @@ const initState = { const store = createStore(rootReducer, initState, compose(applyMiddleware(thunk), initEnhancer(false)), ); - ReactDOM.render(
- +
, exploreViewContainer, diff --git a/superset/templates/superset/basic.html b/superset/templates/superset/basic.html index 87b058d13eff5..ea7f5b12dec1b 100644 --- a/superset/templates/superset/basic.html +++ b/superset/templates/superset/basic.html @@ -41,7 +41,6 @@ {% endblock %} {% block body %} - {% include 'superset/flash_wrapper.html' %}
diff --git a/superset/templates/superset/dashboard.html b/superset/templates/superset/dashboard.html index e297e5116a604..d3e81f25e0f32 100644 --- a/superset/templates/superset/dashboard.html +++ b/superset/templates/superset/dashboard.html @@ -5,8 +5,6 @@ class="dashboard container-fluid" data-bootstrap="{{ bootstrap_data }}" > - {% include 'superset/flash_wrapper.html' %} -
diff --git a/superset/views/base.py b/superset/views/base.py index d03625821c944..6974f71e71c34 100644 --- a/superset/views/base.py +++ b/superset/views/base.py @@ -3,7 +3,7 @@ import logging import traceback -from flask import g, redirect, Response, flash, abort +from flask import g, redirect, Response, flash, abort, get_flashed_messages from flask_babel import gettext as __ from flask_babel import lazy_gettext as _ @@ -17,6 +17,8 @@ from superset.connectors.connector_registry import ConnectorRegistry from superset.connectors.sqla.models import SqlaTable +FRONTEND_CONF_KEYS = ('SUPERSET_WEBSERVER_TIMEOUT',) + def get_error_msg(): if conf.get("SHOW_STACKTRACE"): @@ -186,6 +188,14 @@ def accessible_by_user(self, database, datasource_names, schema=None): full_names = {d.full_name for d in user_datasources} return [d for d in datasource_names if d in full_names] + def common_bootsrap_payload(self): + """Common data always sent to the client""" + messages = get_flashed_messages(with_categories=True) + return { + 'flash_messages': messages, + 'conf': {k: conf.get(k) for k in FRONTEND_CONF_KEYS}, + } + class SupersetModelView(ModelView): page_size = 100 diff --git a/superset/views/core.py b/superset/views/core.py index 85aa460b5ba77..98a0aa66ef8fe 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -1087,6 +1087,7 @@ def explore(self, datasource_type, datasource_id): "standalone": standalone, "user_id": user_id, "forced_height": request.args.get('height'), + 'common': self.common_bootsrap_payload(), } table_name = datasource.table_name \ if datasource_type == 'table' \ @@ -1719,6 +1720,7 @@ def dashboard(**kwargs): # noqa 'user_id': g.user.get_id(), 'dashboard_data': dashboard_data, 'datasources': {ds.uid: ds.data for ds in datasources}, + 'common': self.common_bootsrap_payload(), } return self.render_template( @@ -2268,7 +2270,8 @@ def profile(self, username): 'email': user.email, 'roles': roles, 'permissions': permissions, - } + }, + 'common': self.common_bootsrap_payload(), } return self.render_template( 'superset/basic.html', @@ -2284,6 +2287,7 @@ def sqllab(self): """SQL Editor""" d = { 'defaultDbId': config.get('SQLLAB_DEFAULT_DBID'), + 'common': self.common_bootsrap_payload(), } return self.render_template( 'superset/basic.html',