Get configuration with React Context in APPM store

feature/appm-store/pbac
Jayasanka 5 years ago
parent a34c98aadf
commit 62d0a0480a

@ -1,5 +1,5 @@
import React from "react";
import {Divider, Row, Col, Typography, Button, Drawer} from "antd";
import {Divider, Row, Col, Typography, Button, Drawer, Icon} from "antd";
import StarRatings from "react-star-ratings";
import Reviews from "./review/Reviews";
import "../../../App.css";
@ -16,6 +16,18 @@ class ReleaseView extends React.Component {
if (release == null) {
return null;
}
const platform = app.deviceType;
const defaultPlatformIcons = config.defaultPlatformIcons;
let icon = defaultPlatformIcons.default.icon;
let color = defaultPlatformIcons.default.color;
let theme = defaultPlatformIcons.default.theme;
if (defaultPlatformIcons.hasOwnProperty(platform)) {
icon = defaultPlatformIcons[platform].icon;
color = defaultPlatformIcons[platform].color;
theme = defaultPlatformIcons[platform].theme;
}
return (
<div>
<div className="release">
@ -25,7 +37,6 @@ class ReleaseView extends React.Component {
</Col>
<Col xl={10} sm={11} className="release-title">
<Title level={2}>{app.name}</Title>
<Text>Version : {release.version}</Text><br/>
<StarRatings
rating={release.rating}
starRatedColor="#777"
@ -34,6 +45,17 @@ class ReleaseView extends React.Component {
numberOfStars={5}
name='rating'
/>
<br/>
<Text>Platform : </Text>
<span style={{fontSize: 20, color: color, textAlign: "center"}}>
<Icon
type={icon}
theme={theme}
/>
</span>
<Divider type="vertical"/>
<Text>Version : {release.version}</Text><br/>
<EditRelease uuid={release.uuid} type={app.type}/>
</Col>
<Col xl={8} md={10} sm={24} xs={24} style={{float: "right"}}>

@ -3,30 +3,89 @@ import "antd/dist/antd.less";
import RouteWithSubRoutes from "./components/RouteWithSubRoutes";
import {
BrowserRouter as Router,
Link, Redirect, Switch,
Redirect, Switch,
} from 'react-router-dom';
import axios from "axios";
import {Layout, Spin, Result} from "antd";
import ConfigContext from "./context/ConfigContext";
const {Content} = Layout;
const loadingView = (
<Layout>
<Content style={{
padding: '0 0',
paddingTop: 300,
backgroundColor: '#fff',
textAlign: 'center'
}}>
<Spin tip="Loading..."/>
</Content>
</Layout>
);
const errorView = (
<Result
style={{
paddingTop: 200
}}
status="500"
title="Error occurred while loading the configuration"
subTitle="Please refresh your browser window"
/>
);
class App extends React.Component {
routes;
constructor(props) {
super(props);
this.routes = props.routes;
this.state = {
loading: true,
error: false,
config: {}
}
}
componentDidMount() {
axios.get(
window.location.origin + "/store/public/conf/config.json",
).then(res => {
console.log(res);
this.setState({
loading: false,
config: res.data
})
}).catch((error) => {
this.setState({
loading: false,
error: true
})
});
}
render() {
return (
const {loading, error} = this.state;
const applicationView = (
<Router>
<ConfigContext.Provider value={this.state.config}>
<div>
<Switch>
<Redirect exact from="/store" to="/store/android"/>
{this.routes.map((route) => (
{this.props.routes.map((route) => (
<RouteWithSubRoutes key={route.path} {...route} />
))}
</Switch>
</div>
</ConfigContext.Provider>
</Router>
);
return (
<div>
{loading && loadingView}
{!loading && !error && applicationView}
{error && errorView}
</div>
);
}
}

@ -2,7 +2,7 @@ import React from "react";
import AppCard from "./AppCard";
import {Col, message, notification, Row, Result, Skeleton} from "antd";
import axios from "axios";
import config from "../../../public/conf/config.json";
import {withConfigContext} from "../../context/ConfigContext";
class AppList extends React.Component {
constructor(props) {
@ -29,7 +29,7 @@ class AppList extends React.Component {
}
fetchData = (deviceType) => {
const config = this.props.context;
const payload = {};
if (deviceType === "web-clip") {
payload.appType = "WEB_CLIP";
@ -99,4 +99,4 @@ class AppList extends React.Component {
}
}
export default AppList;
export default withConfigContext(AppList);

@ -2,8 +2,8 @@ import React from "react";
import {Row, Typography, Icon} from "antd";
import StarRatings from "react-star-ratings";
import "./DetailedRating.css";
import config from "../../../../public/conf/config.json";
import axios from "axios";
import {withConfigContext} from "../../../context/ConfigContext";
const { Text } = Typography;
@ -30,6 +30,7 @@ class DetailedRating extends React.Component{
}
getData = (type, uuid)=>{
const config = this.props.context;
return axios.get(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.store+"/reviews/"+uuid+"/"+type+"-rating",
@ -117,4 +118,4 @@ class DetailedRating extends React.Component{
}
export default DetailedRating;
export default withConfigContext(DetailedRating);

@ -5,11 +5,10 @@ import ImgViewer from "../../apps/release/images/ImgViewer";
import StarRatings from "react-star-ratings";
import DetailedRating from "./DetailedRating";
import Reviews from "./review/Reviews";
import AddReview from "./review/AddReview";
import axios from "axios";
import config from "../../../../public/conf/config.json";
import AppInstallModal from "./install/AppInstallModal";
import CurrentUsersReview from "./review/CurrentUsersReview";
import {withConfigContext} from "../../../context/ConfigContext";
const {Title, Text, Paragraph} = Typography;
@ -23,6 +22,7 @@ class ReleaseView extends React.Component {
}
installApp = (type, payload) => {
const config = this.props.context;
const release = this.props.app.applicationReleases[0];
const {uuid} = release;
@ -150,4 +150,4 @@ class ReleaseView extends React.Component {
}
}
export default ReleaseView;
export default withConfigContext(ReleaseView);

@ -1,11 +1,11 @@
import React from "react";
import axios from "axios";
import config from "../../../../../public/conf/config.json";
import {Button, message, notification, Table, Typography} from "antd";
import TimeAgo from 'javascript-time-ago'
// Load locale-specific relative date/time formatting rules.
import en from 'javascript-time-ago/locale/en'
import {withConfigContext} from "../../../../context/ConfigContext";
const {Text} = Typography;
const columns = [
{
@ -112,6 +112,7 @@ class DeviceInstall extends React.Component {
//fetch data from api
fetch = (params = {}) => {
const config = this.props.context;
this.setState({loading: true});
const {deviceType} = this.props;
// get current page
@ -219,4 +220,4 @@ class DeviceInstall extends React.Component {
}
}
export default DeviceInstall;
export default withConfigContext(DeviceInstall);

@ -2,7 +2,7 @@ import React from "react";
import {Typography, Select, Spin, message, notification, Button} from "antd";
import debounce from 'lodash.debounce';
import axios from "axios";
import config from "../../../../../public/conf/config.json";
import {withConfigContext} from "../../../../context/ConfigContext";
const {Text} = Typography;
const {Option} = Select;
@ -25,6 +25,7 @@ class GroupInstall extends React.Component {
fetchUser = value => {
this.lastFetchId += 1;
const fetchId = this.lastFetchId;
const config = this.props.context;
this.setState({data: [], fetching: true});
axios.post(
@ -111,4 +112,4 @@ class GroupInstall extends React.Component {
}
}
export default GroupInstall;
export default withConfigContext(GroupInstall);

@ -2,7 +2,7 @@ import React from "react";
import {Typography, Select, Spin, message, notification, Button} from "antd";
import debounce from 'lodash.debounce';
import axios from "axios";
import config from "../../../../../public/conf/config.json";
import {withConfigContext} from "../../../../context/ConfigContext";
const {Text} = Typography;
const {Option} = Select;
@ -23,6 +23,7 @@ class RoleInstall extends React.Component {
};
fetchUser = value => {
const config = this.props.context;
this.lastFetchId += 1;
const fetchId = this.lastFetchId;
this.setState({data: [], fetching: true});
@ -111,4 +112,4 @@ class RoleInstall extends React.Component {
}
}
export default RoleInstall;
export default withConfigContext(RoleInstall);

@ -2,7 +2,7 @@ import React from "react";
import {Typography, Select, Spin, message, notification, Button} from "antd";
import debounce from 'lodash.debounce';
import axios from "axios";
import config from "../../../../../public/conf/config.json";
import {withConfigContext} from "../../../../context/ConfigContext";
const {Text} = Typography;
const {Option} = Select;
@ -23,6 +23,7 @@ class UserInstall extends React.Component {
};
fetchUser = value => {
const config = this.props.context;
this.lastFetchId += 1;
const fetchId = this.lastFetchId;
this.setState({data: [], fetching: true});
@ -111,4 +112,4 @@ class UserInstall extends React.Component {
}
}
export default UserInstall;
export default withConfigContext(UserInstall);

@ -2,7 +2,7 @@ import React from "react";
import {Drawer, Button, Icon, Row, Col, Typography, Divider, Input, Spin, notification} from 'antd';
import StarRatings from "react-star-ratings";
import axios from "axios";
import config from "../../../../../public/conf/config.json";
import {withConfigContext} from "../../../../context/ConfigContext";
const {Title} = Typography;
const {TextArea} = Input;
@ -41,6 +41,7 @@ class AddReview extends React.Component {
};
onSubmit = () => {
const config = this.props.context;
const {content, rating} = this.state;
const {uuid} = this.props;
this.setState({
@ -159,4 +160,4 @@ class AddReview extends React.Component {
}
}
export default AddReview;
export default withConfigContext(AddReview);

@ -2,8 +2,8 @@ import React from "react";
import {List, message, Typography, Empty, Button, Row, Col, notification} from "antd";
import SingleReview from "./singleReview/SingleReview";
import axios from "axios";
import config from "../../../../../public/conf/config.json";
import AddReview from "./AddReview";
import {withConfigContext} from "../../../../context/ConfigContext";
const {Text, Paragraph} = Typography;
@ -23,6 +23,7 @@ class CurrentUsersReview extends React.Component {
fetchData = () => {
const {uuid} = this.props;
const config = this.props.context;
axios.get(
config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/reviews/app/user/" + uuid,
@ -106,4 +107,4 @@ class CurrentUsersReview extends React.Component {
}
export default CurrentUsersReview;
export default withConfigContext(CurrentUsersReview);

@ -5,7 +5,7 @@ import "./Reviews.css";
import InfiniteScroll from 'react-infinite-scroller';
import SingleReview from "./singleReview/SingleReview";
import axios from "axios";
import config from "../../../../../public/conf/config.json";
import {withConfigContext} from "../../../../context/ConfigContext";
const limit = 5;
@ -29,6 +29,7 @@ class Reviews extends React.Component {
fetchData = (offset, limit, callback) => {
const {uuid, type} = this.props;
const config = this.props.context;
axios.get(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri +config.serverConfig.invoker.store+"/reviews/"+type+"/"+uuid,
@ -133,4 +134,4 @@ class Reviews extends React.Component {
}
}
export default Reviews;
export default withConfigContext(Reviews);

@ -6,7 +6,7 @@ import Twemoji from "react-twemoji";
import "./SingleReview.css";
import EditReview from "./editReview/EditReview";
import axios from "axios";
import config from "../../../../../../public/conf/config.json";
import {withConfigContext} from "../../../../../context/ConfigContext";
const {Text, Paragraph} = Typography;
const colorList = ['#f0932b', '#badc58', '#6ab04c', '#eb4d4b', '#0abde3', '#9b59b6', '#3498db', '#22a6b3', '#e84393', '#f9ca24'];
@ -38,6 +38,7 @@ class SingleReview extends React.Component {
deleteReview = () => {
const {uuid} = this.props;
const {id} = this.state.review;
const config = this.props.context;
let url = config.serverConfig.protocol + "://" + config.serverConfig.hostname + ':' +
config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.store;
@ -131,4 +132,4 @@ class SingleReview extends React.Component {
}
}
export default SingleReview;
export default withConfigContext(SingleReview);

@ -2,8 +2,8 @@ import React from "react";
import {Drawer, Button, Icon, Row, Col, Typography, Divider, Input, Spin, notification} from 'antd';
import StarRatings from "react-star-ratings";
import axios from "axios";
import config from "../../../../../../../public/conf/config.json";
import "./EditReview.css";
import {withConfigContext} from "../../../../../../context/ConfigContext";
const {Title} = Typography;
const {TextArea} = Input;
@ -54,6 +54,7 @@ class EditReview extends React.Component {
};
onSubmit = () => {
const config = this.props.context;
const {content, rating} = this.state;
const {id} = this.props.review;
const {uuid} = this.props;
@ -169,4 +170,4 @@ class EditReview extends React.Component {
}
}
export default EditReview;
export default withConfigContext(EditReview);

@ -0,0 +1,16 @@
import React from "react";
const ConfigContext = React.createContext();
export const withConfigContext = Component => {
return props => (
<ConfigContext.Consumer>
{context => {
return <Component {...props} context={context}/>;
}}
</ConfigContext.Consumer>
);
};
export default ConfigContext;

@ -38,7 +38,7 @@ ReactDOM.render(
<App routes={routes}/>,
document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// If you want your app e and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

@ -1,56 +0,0 @@
import * as dagre from "dagre";
import * as _ from "lodash";
const size = {
width: 60,
height: 60
};
export function distributeElements(model) {
let clonedModel = _.cloneDeep(model);
let nodes = distributeGraph(clonedModel);
nodes.forEach(node => {
let modelNode = clonedModel.nodes.find(item => item.id === node.id);
modelNode.x = node.x - node.width / 2;
modelNode.y = node.y - node.height / 2;
});
return clonedModel;
}
function distributeGraph(model) {
let nodes = mapElements(model);
let edges = mapEdges(model);
let graph = new dagre.graphlib.Graph();
graph.setGraph({});
graph.setDefaultEdgeLabel(() => ({}));
//add elements to dagre graph
nodes.forEach(node => {
graph.setNode(node.id, node.metadata);
});
edges.forEach(edge => {
if (edge.from && edge.to) {
graph.setEdge(edge.from, edge.to);
}
});
//auto-distribute
dagre.layout(graph);
return graph.nodes().map(node => graph.node(node));
}
function mapElements(model) {
// dagre compatible format
return model.nodes.map(node => ({ id: node.id, metadata: { ...size, id: node.id } }));
}
function mapEdges(model) {
// returns links which connects nodes
// we check are there both from and to nodes in the model. Sometimes links can be detached
return model.links
.map(link => ({
from: link.source,
to: link.target
}))
.filter(
item => model.nodes.find(node => node.id === item.from) && model.nodes.find(node => node.id === item.to)
);
}

@ -2,7 +2,7 @@ import React from "react";
import {Typography, Row, Col, Form, Icon, Input, Button, Checkbox} from 'antd';
import './Login.css';
import axios from 'axios';
import config from "../../public/conf/config.json";
import {withConfigContext} from "../context/ConfigContext";
const {Title} = Typography;
const {Text} = Typography;
@ -59,6 +59,8 @@ class NormalLoginForm extends React.Component {
handleSubmit = (e) => {
const thisForm = this;
const config = this.props.context;
e.preventDefault();
this.props.form.validateFields((err, values) => {
thisForm.setState({
@ -146,4 +148,4 @@ class NormalLoginForm extends React.Component {
const WrappedNormalLoginForm = Form.create({name: 'normal_login'})(NormalLoginForm);
export default Login;
export default withConfigContext(Login);

@ -5,16 +5,16 @@ import {Link} from "react-router-dom";
import RouteWithSubRoutes from "../../components/RouteWithSubRoutes"
import {Switch} from 'react-router'
import "../../App.css";
import config from "../../../public/conf/config.json";
import {withConfigContext} from "../../context/ConfigContext";
class Dashboard extends React.Component {
constructor(props) {
super(props);
this.state = {
routes: props.routes,
selectedKeys : []
selectedKeys: []
};
this.Logo = config.theme.logo;
this.logo = this.props.context.theme.logo;
}
changeSelectedMenuItem = (key) =>{
@ -30,7 +30,7 @@ class Dashboard extends React.Component {
<Layout className="layout">
<Header style={{paddingLeft: 0, paddingRight: 0}}>
<div className="logo-image">
<img alt="logo" src={this.Logo}/>
<img alt="logo" src={this.logo}/>
</div>
<Menu
theme="light"
@ -63,4 +63,4 @@ class Dashboard extends React.Component {
}
}
export default Dashboard;
export default withConfigContext(Dashboard);

@ -3,7 +3,7 @@ import '../../../../App.css';
import {Skeleton, Typography, Row, Col, Card, message, notification} from "antd";
import ReleaseView from "../../../../components/apps/release/ReleaseView";
import axios from "axios";
import config from "../../../../../public/conf/config.json";
import {withConfigContext} from "../../../../context/ConfigContext";
const {Title} = Typography;
@ -36,6 +36,8 @@ class Release extends React.Component {
}
fetchData = (uuid)=>{
const config = this.props.context;
//send request to the invoker
axios.get(
config.serverConfig.protocol + "://"+config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invoker.uri + config.serverConfig.invoker.store+"/applications/"+uuid,
@ -101,4 +103,4 @@ class Release extends React.Component {
}
export default Release;
export default withConfigContext(Release);

Loading…
Cancel
Save