diff --git a/scm-plugins/scm-git-plugin/package.json b/scm-plugins/scm-git-plugin/package.json index a01cefe503..c679f259c8 100644 --- a/scm-plugins/scm-git-plugin/package.json +++ b/scm-plugins/scm-git-plugin/package.json @@ -5,7 +5,7 @@ "build": "ui-bundler plugin" }, "dependencies": { - "@scm-manager/ui-extensions": "^0.0.5" + "@scm-manager/ui-extensions": "^0.0.6" }, "devDependencies": { "@scm-manager/ui-bundler": "^0.0.3" diff --git a/scm-plugins/scm-hg-plugin/package.json b/scm-plugins/scm-hg-plugin/package.json index 3f08153700..ff7e9ab6b3 100644 --- a/scm-plugins/scm-hg-plugin/package.json +++ b/scm-plugins/scm-hg-plugin/package.json @@ -5,7 +5,7 @@ "build": "ui-bundler plugin" }, "dependencies": { - "@scm-manager/ui-extensions": "^0.0.5" + "@scm-manager/ui-extensions": "^0.0.6" }, "devDependencies": { "@scm-manager/ui-bundler": "^0.0.3" diff --git a/scm-plugins/scm-svn-plugin/package.json b/scm-plugins/scm-svn-plugin/package.json index fa91fc4969..195897cbbe 100644 --- a/scm-plugins/scm-svn-plugin/package.json +++ b/scm-plugins/scm-svn-plugin/package.json @@ -5,7 +5,7 @@ "build": "ui-bundler plugin" }, "dependencies": { - "@scm-manager/ui-extensions": "^0.0.5" + "@scm-manager/ui-extensions": "^0.0.6" }, "devDependencies": { "@scm-manager/ui-bundler": "^0.0.3" diff --git a/scm-ui/package.json b/scm-ui/package.json index 49c83aee38..267e2926ce 100644 --- a/scm-ui/package.json +++ b/scm-ui/package.json @@ -5,7 +5,7 @@ "private": true, "main": "src/index.js", "dependencies": { - "@scm-manager/ui-extensions": "^0.0.5", + "@scm-manager/ui-extensions": "^0.0.6", "bulma": "^0.7.1", "classnames": "^2.2.5", "font-awesome": "^4.7.0", diff --git a/scm-ui/public/index.html b/scm-ui/public/index.html index 8a6237c9b9..c76e55cac3 100644 --- a/scm-ui/public/index.html +++ b/scm-ui/public/index.html @@ -39,8 +39,5 @@ --> - - - diff --git a/scm-ui/src/components/Loading.js b/scm-ui/src/components/Loading.js index 0cf0d16fbe..f76e1be05b 100644 --- a/scm-ui/src/components/Loading.js +++ b/scm-ui/src/components/Loading.js @@ -25,12 +25,13 @@ const styles = { type Props = { t: string => string, + message?: string, classes: any }; class Loading extends React.Component { render() { - const { t, classes } = this.props; + const { message, t, classes } = this.props; return (
@@ -39,6 +40,7 @@ class Loading extends React.Component { src="/images/loading.svg" alt={t("loading.alt")} /> +

{message}

); diff --git a/scm-ui/src/components/PluginLoader.js b/scm-ui/src/components/PluginLoader.js new file mode 100644 index 0000000000..48dbd20a6a --- /dev/null +++ b/scm-ui/src/components/PluginLoader.js @@ -0,0 +1,93 @@ +// @flow +import * as React from "react"; +import Loading from "./Loading"; +import { apiClient } from "../apiclient"; + +type Props = { + children: React.Node +}; + +type State = { + finished: boolean, + message: string +}; + +type Plugin = { + id: string, + bundles: string[] +}; + +class PluginLoader extends React.Component { + constructor(props: Props) { + super(props); + this.state = { + finished: false, + message: "booting" + }; + } + + componentDidMount() { + this.setState({ + message: "loading plugin information" + }); + apiClient + .get("ui/plugins") + .then(response => response.text()) + .then(JSON.parse) + .then(this.loadPlugins) + .then(() => { + this.setState({ + finished: true + }); + }); + } + + loadPlugins = (plugins: Plugin[]) => { + this.setState({ + message: "loading plugins" + }); + + const promises = []; + for (let plugin of plugins) { + promises.push(this.loadPlugin(plugin)); + } + return Promise.all(promises); + }; + + loadPlugin = (plugin: Plugin) => { + this.setState({ + message: `loading ${plugin.name}` + }); + + const promises = []; + for (let bundle of plugin.bundles) { + // skip old bundles + // TODO remove old bundles + if (bundle.indexOf("/") !== 0) { + promises.push(this.loadBundle(bundle)); + } + } + return Promise.all(promises); + }; + + loadBundle = (bundle: string) => { + return fetch(bundle) + .then(response => { + return response.text(); + }) + .then(script => { + // TODO is this safe??? + eval(script); + }); + }; + + render() { + const { message, finished } = this.state; + if (finished) { + return
{this.props.children}
; + } + return ; + } +} + +export default PluginLoader; diff --git a/scm-ui/src/index.js b/scm-ui/src/index.js index ea133dd55b..d013bb946a 100644 --- a/scm-ui/src/index.js +++ b/scm-ui/src/index.js @@ -14,6 +14,7 @@ import type { BrowserHistory } from "history/createBrowserHistory"; import createReduxStore from "./createReduxStore"; import { ConnectedRouter } from "react-router-redux"; +import PluginLoader from "./components/PluginLoader"; const publicUrl: string = process.env.PUBLIC_URL || ""; @@ -36,7 +37,9 @@ ReactDOM.render( {/* ConnectedRouter will use the store from Provider automatically */} - + + + ,