mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 23:45:44 +01:00
implemented PluginLoader
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -39,8 +39,5 @@
|
||||
-->
|
||||
<script src="vendor.bundle.js"></script>
|
||||
<script src="scm-ui.bundle.js"></script>
|
||||
<script src="scm-git-plugin.bundle.js"></script>
|
||||
<script src="scm-hg-plugin.bundle.js"></script>
|
||||
<script src="scm-svn-plugin.bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -25,12 +25,13 @@ const styles = {
|
||||
|
||||
type Props = {
|
||||
t: string => string,
|
||||
message?: string,
|
||||
classes: any
|
||||
};
|
||||
|
||||
class Loading extends React.Component<Props> {
|
||||
render() {
|
||||
const { t, classes } = this.props;
|
||||
const { message, t, classes } = this.props;
|
||||
return (
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classes.loading}>
|
||||
@@ -39,6 +40,7 @@ class Loading extends React.Component<Props> {
|
||||
src="/images/loading.svg"
|
||||
alt={t("loading.alt")}
|
||||
/>
|
||||
<p className="has-text-centered">{message}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
93
scm-ui/src/components/PluginLoader.js
Normal file
93
scm-ui/src/components/PluginLoader.js
Normal file
@@ -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<Props, State> {
|
||||
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 <div>{this.props.children}</div>;
|
||||
}
|
||||
return <Loading message={message} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginLoader;
|
||||
@@ -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(
|
||||
<I18nextProvider i18n={i18n}>
|
||||
{/* ConnectedRouter will use the store from Provider automatically */}
|
||||
<ConnectedRouter history={history}>
|
||||
<App />
|
||||
<PluginLoader>
|
||||
<App />
|
||||
</PluginLoader>
|
||||
</ConnectedRouter>
|
||||
</I18nextProvider>
|
||||
</Provider>,
|
||||
|
||||
Reference in New Issue
Block a user