You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by su...@apache.org on 2020/08/10 23:31:38 UTC
[incubator-superset] 01/06: first attempts at dynamic plugin loading
This is an automated email from the ASF dual-hosted git repository.
suddjian pushed a commit to branch dynamic-plugin-import
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
commit 9b0dfc4f54159b23054a6d57a95c6fc9b3af2e65
Author: David Aaron Suddjian <aa...@gmail.com>
AuthorDate: Wed Jun 10 14:30:03 2020 -0700
first attempts at dynamic plugin loading
---
superset-frontend/src/addSlice/App.tsx | 5 +-
.../DynamicPlugins/DynamicPluginProvider.tsx | 40 +++++++++++++
.../src/components/DynamicPlugins/PluginContext.ts | 25 +++++++++
superset-frontend/src/welcome/App.tsx | 65 +++++++++++-----------
4 files changed, 103 insertions(+), 32 deletions(-)
diff --git a/superset-frontend/src/addSlice/App.tsx b/superset-frontend/src/addSlice/App.tsx
index 4443fb5..f94b4da 100644
--- a/superset-frontend/src/addSlice/App.tsx
+++ b/superset-frontend/src/addSlice/App.tsx
@@ -21,6 +21,7 @@ import { hot } from 'react-hot-loader/root';
import { supersetTheme, ThemeProvider } from '@superset-ui/style';
import setupApp from '../setup/setupApp';
import setupPlugins from '../setup/setupPlugins';
+import DynamicPluginProvider from '../components/DynamicPlugins/DynamicPluginProvider';
import AddSliceContainer from './AddSliceContainer';
setupApp();
@@ -33,7 +34,9 @@ const bootstrapData = JSON.parse(
const App = () => (
<ThemeProvider theme={supersetTheme}>
- <AddSliceContainer datasources={bootstrapData.datasources} />
+ <DynamicPluginProvider>
+ <AddSliceContainer datasources={bootstrapData.datasources} />
+ </DynamicPluginProvider>
</ThemeProvider>
);
diff --git a/superset-frontend/src/components/DynamicPlugins/DynamicPluginProvider.tsx b/superset-frontend/src/components/DynamicPlugins/DynamicPluginProvider.tsx
new file mode 100644
index 0000000..ca45e66
--- /dev/null
+++ b/superset-frontend/src/components/DynamicPlugins/DynamicPluginProvider.tsx
@@ -0,0 +1,40 @@
+import React, { useEffect, useState } from 'react';
+// use scriptjs for browser-side dynamic importing
+// import $script from 'scriptjs';
+// import { Preset } from '@superset-ui/core';
+import PluginContext, { initialPluginContext } from './PluginContext';
+
+console.log('from superset:', React);
+
+// In future this should be provided by an api call
+const pluginUrls = ['http://localhost:8080/main.js'];
+
+export type Props = React.PropsWithChildren<{}>;
+
+export default function DynamicPluginProvider({ children }: Props) {
+ const [pluginState] = useState(initialPluginContext);
+ useEffect(() => {
+ console.log('importing test');
+ // $script(pluginUrls, () => {
+ // console.log('done');
+ // });
+ Promise.all(
+ pluginUrls.map(async url => {
+ const { default: d } = await import(/* webpackIgnore: true */ url);
+ return d;
+ }),
+ ).then(pluginModules => {
+ console.log(pluginModules);
+ // return new Preset({
+ // name: 'Dynamic Charts',
+ // presets: [],
+ // plugins: [pluginModules],
+ // });
+ });
+ }, [pluginUrls]);
+ return (
+ <PluginContext.Provider value={pluginState}>
+ {children}
+ </PluginContext.Provider>
+ );
+}
diff --git a/superset-frontend/src/components/DynamicPlugins/PluginContext.ts b/superset-frontend/src/components/DynamicPlugins/PluginContext.ts
new file mode 100644
index 0000000..100e813
--- /dev/null
+++ b/superset-frontend/src/components/DynamicPlugins/PluginContext.ts
@@ -0,0 +1,25 @@
+import React from 'react';
+
+export enum LoadingStatus {
+ LOADING = 'loading',
+ COMPLETE = 'complete',
+ ERROR = 'error',
+}
+
+export type PluginContextType = {
+ status: LoadingStatus;
+ error: null | {
+ message: string;
+ };
+ pluginKeys: string[];
+};
+
+export const initialPluginContext: PluginContextType = {
+ status: LoadingStatus.LOADING,
+ error: null,
+ pluginKeys: [],
+};
+
+const PluginContext = React.createContext(initialPluginContext);
+
+export default PluginContext;
diff --git a/superset-frontend/src/welcome/App.tsx b/superset-frontend/src/welcome/App.tsx
index 5bc624d..c72a131 100644
--- a/superset-frontend/src/welcome/App.tsx
+++ b/superset-frontend/src/welcome/App.tsx
@@ -20,7 +20,7 @@ import React from 'react';
import { hot } from 'react-hot-loader/root';
import thunk from 'redux-thunk';
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
-import { Provider } from 'react-redux';
+import { Provider as ReduxProvider } from 'react-redux';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { QueryParamProvider } from 'use-query-params';
import { initFeatureFlags } from 'src/featureFlags';
@@ -38,6 +38,7 @@ import setupApp from '../setup/setupApp';
import setupPlugins from '../setup/setupPlugins';
import Welcome from './Welcome';
import ToastPresenter from '../messageToasts/containers/ToastPresenter';
+import DynamicPluginProvider from 'src/components/DynamicPlugins/DynamicPluginProvider';
setupApp();
setupPlugins();
@@ -58,40 +59,42 @@ const store = createStore(
);
const App = () => (
- <Provider store={store}>
+ <ReduxProvider store={store}>
<ThemeProvider theme={supersetTheme}>
<FlashProvider common={common}>
- <Router>
- <QueryParamProvider ReactRouterRoute={Route}>
- <Menu data={menu} />
- <Switch>
- <Route path="/superset/welcome/">
- <ErrorBoundary>
- <Welcome user={user} />
- </ErrorBoundary>
- </Route>
- <Route path="/dashboard/list/">
- <ErrorBoundary>
- <DashboardList user={user} />
- </ErrorBoundary>
- </Route>
- <Route path="/chart/list/">
- <ErrorBoundary>
- <ChartList user={user} />
- </ErrorBoundary>
- </Route>
- <Route path="/tablemodelview/list/">
- <ErrorBoundary>
- <DatasetList user={user} />
- </ErrorBoundary>
- </Route>
- </Switch>
- <ToastPresenter />
- </QueryParamProvider>
- </Router>
+ <DynamicPluginProvider>
+ <Router>
+ <QueryParamProvider ReactRouterRoute={Route}>
+ <Menu data={menu} />
+ <Switch>
+ <Route path="/superset/welcome/">
+ <ErrorBoundary>
+ <Welcome user={user} />
+ </ErrorBoundary>
+ </Route>
+ <Route path="/dashboard/list/">
+ <ErrorBoundary>
+ <DashboardList user={user} />
+ </ErrorBoundary>
+ </Route>
+ <Route path="/chart/list/">
+ <ErrorBoundary>
+ <ChartList user={user} />
+ </ErrorBoundary>
+ </Route>
+ <Route path="/tablemodelview/list/">
+ <ErrorBoundary>
+ <DatasetList user={user} />
+ </ErrorBoundary>
+ </Route>
+ </Switch>
+ <ToastPresenter />
+ </QueryParamProvider>
+ </Router>
+ </DynamicPluginProvider>
</FlashProvider>
</ThemeProvider>
- </Provider>
+ </ReduxProvider>
);
export default hot(App);