Merge branch 'application-mgt-new' into 'application-mgt-new'

Publisher: View Releases

See merge request entgra/carbon-device-mgt!84
feature/appm-store/pbac
Dharmakeerthi Lasantha 6 years ago
commit 8926e7ffd8

@ -13,6 +13,7 @@
"acorn": "^6.1.1", "acorn": "^6.1.1",
"antd": "^3.15.0", "antd": "^3.15.0",
"axios": "^0.18.0", "axios": "^0.18.0",
"keymirror": "^0.1.1",
"react": "^16.8.4", "react": "^16.8.4",
"react-dom": "^16.8.4", "react-dom": "^16.8.4",
"react-highlight-words": "^0.16.0", "react-highlight-words": "^0.16.0",

@ -2,15 +2,26 @@ import {
Skeleton, Switch, Card, Icon, Avatar, Typography Skeleton, Switch, Card, Icon, Avatar, Typography
} from 'antd'; } from 'antd';
import React from "react"; import React from "react";
import config from "../../public/conf/config.json"; import config from "../../../public/conf/config.json";
import {openReleasesModal} from "../../js/actions";
import {connect} from "react-redux";
const { Meta } = Card; const { Meta } = Card;
const { Text } = Typography; const { Text } = Typography;
class AppCard extends React.Component { const mapDispatchToProps = dispatch => ({
openReleasesModal: (app) => dispatch(openReleasesModal(app))
});
class ConnectedAppCard extends React.Component {
constructor(props){ constructor(props){
super(props); super(props);
this.handleReleasesClick = this.handleReleasesClick.bind(this);
}
handleReleasesClick(){
this.props.openReleasesModal(this.props.app);
} }
@ -33,7 +44,7 @@ class AppCard extends React.Component {
); );
return ( return (
<Card style={{marginTop: 16 }} actions={[<Icon type="edit" />, <Icon type="close" />, <Icon type="ellipsis" />]}> <Card style={{marginTop: 16 }} actions={[<Icon type="edit" />, <Icon type="delete" />, <Icon type="appstore" theme="twoTone" onClick={this.handleReleasesClick} />]}>
<Meta <Meta
avatar={<Avatar src={icon} />} avatar={<Avatar src={icon} />}
title={this.props.name} title={this.props.name}
@ -44,4 +55,6 @@ class AppCard extends React.Component {
} }
} }
const AppCard = connect(null,mapDispatchToProps)(ConnectedAppCard);
export default AppCard; export default AppCard;

@ -2,9 +2,9 @@ import React from "react";
import AppCard from "./AppCard"; import AppCard from "./AppCard";
import {Col, Row} from "antd"; import {Col, Row} from "antd";
import {connect} from "react-redux"; import {connect} from "react-redux";
import {getApps} from "../js/actions"; import {getApps} from "../../js/actions";
// connecting state.articles with the component // connecting state.apps with the component
const mapStateToProps= state => { const mapStateToProps= state => {
return {apps : state.apps} return {apps : state.apps}
}; };
@ -24,6 +24,7 @@ class ConnectedAppList extends React.Component {
{this.props.apps.map(app => ( {this.props.apps.map(app => (
<Col key={app.id} xs={24} sm={12} md={6} lg={6}> <Col key={app.id} xs={24} sm={12} md={6} lg={6}>
<AppCard key={app.id} <AppCard key={app.id}
app = {app}
name={app.name} name={app.name}
platform={app.deviceType} platform={app.deviceType}
type={app.type} type={app.type}

@ -0,0 +1,85 @@
import React from "react";
import {Modal, Typography,List, Avatar} from 'antd';
import {connect} from 'react-redux';
import {Link} from "react-router-dom";
// connecting state.releaseView with the component
const mapStateToProps = state => {
return {releaseView: state.releaseView}
};
const Text = Typography;
class ConnectedReleaseModal extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: false,
app: null
};
}
componentWillReceiveProps(nextProps) {
if (nextProps !== this.props) {
this.setState({
visible: nextProps.releaseView.visible,
app: nextProps.releaseView.app
})
}
}
showModal = () => {
this.setState({
visible: true,
});
};
handleOk = (e) => {
this.setState({
visible: false,
});
};
handleCancel = (e) => {
this.setState({
visible: false,
});
};
render() {
if (this.props.releaseView.app != null) {
const app = this.props.releaseView.app;
return (
<div>
<Modal
title={app.name}
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
>
<p>Some contents...</p>
<List
itemLayout="horizontal"
dataSource={app.applicationReleases}
renderItem={release => (
<List.Item>
<List.Item.Meta
avatar={<Avatar src={release.iconPath} />}
title={<Link to={"/publisher/apps/releases/"+release.uuid}>{release.version}</Link>}
description={release.description}
/>
</List.Item>
)}
/>
</Modal>
</div>
);
} else {
return null;
}
}
}
const ReleaseModal = connect(mapStateToProps, null)(ConnectedReleaseModal);
export default ReleaseModal;

@ -0,0 +1,33 @@
import React from "react";
import {Avatar, Row, Col, Typography} from "antd";
const {Title, Text} = Typography;
class ReleaseView extends React.Component {
render() {
const release = this.props.release;
return (
<div>
<Row>
<Col span={4}>
<Avatar size={128} shape="square"
src={release.iconPath}/>
</Col>
<Col span={18}>
<Title level={2}>App Name</Title>
<Text>{release.version}</Text><br/>
<Text type="secondary">{release.description}</Text>
</Col>
</Row>
<br/>
<Row>
<Col span={6}>
<img style={{width:"100%"}} src={release.screenshotPath1}/>
</Col>
</Row>
</div>
);
}
}
export default ReleaseView;

@ -5,6 +5,7 @@ import App from "./App";
import Login from "./pages/Login"; import Login from "./pages/Login";
import Dashboard from "./pages/dashboard/Dashboard"; import Dashboard from "./pages/dashboard/Dashboard";
import Apps from "./pages/dashboard/apps/Apps"; import Apps from "./pages/dashboard/apps/Apps";
import Release from "./pages/dashboard/apps/release/Release";
import AddNewApp from "./pages/dashboard/add-new-app/AddNewApp"; import AddNewApp from "./pages/dashboard/add-new-app/AddNewApp";
import './index.css'; import './index.css';
import store from "./js/store/index"; import store from "./js/store/index";
@ -31,6 +32,11 @@ const routes = [
path: '/publisher/apps/new-app', path: '/publisher/apps/new-app',
component: AddNewApp, component: AddNewApp,
exact: true exact: true
},
{
path: '/publisher/apps/releases/:uuid',
exact: true,
component: Release
} }
] ]
} }

@ -1,22 +1,21 @@
import axios from "axios"; import axios from "axios";
import {GET_APPS} from "../constants/action-types"; import ActionTypes from "../constants/ActionTypes";
import config from "../../../public/conf/config.json"; import config from "../../../public/conf/config.json";
export function getApps() { export const getApps = () => dispatch => {
return (dispatch) => {
const request = "method=post&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/applications"; const request = "method=post&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/applications";
return axios.post('https://'+config.serverConfig.hostname+':'+config.serverConfig.httpsPort+config.serverConfig.invokerUri, request return axios.post('https://' + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invokerUri, request
).then(res => { ).then(res => {
if (res.status === 200) { if (res.status === 200) {
let apps = []; let apps = [];
if(res.data.data.hasOwnProperty("applications")){ if (res.data.data.hasOwnProperty("applications")) {
apps = res.data.data.applications; apps = res.data.data.applications;
} }
console.log(res.data); console.log(res.data);
dispatch({type: GET_APPS, payload: apps}); dispatch({type: ActionTypes.GET_APPS, payload: apps});
} }
}).catch(function (error) { }).catch(function (error) {
@ -25,7 +24,38 @@ export function getApps() {
} }
}); });
};
};
export const getRelease = (uuid) => dispatch => {
const request = "method=get&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/applications/release/"+uuid;
return axios.post('https://' + config.serverConfig.hostname + ':' + config.serverConfig.httpsPort + config.serverConfig.invokerUri, request
).then(res => {
if (res.status === 200) {
let release = res.data.data;
console.log(res.data);
dispatch({type: ActionTypes.GET_RELEASE, payload: release});
}
}).catch(function (error) {
if (error.response.status === 401) {
window.location.href = 'https://localhost:9443/publisher/login';
}
});
};
export const openReleasesModal = (app) => dispatch => {
console.log(app);
dispatch({
type: ActionTypes.OPEN_RELEASES_MODAL,
payload: {
app:app
}
});
};
}

@ -0,0 +1,17 @@
import keyMirror from 'keymirror';
// export const LOGIN = "LOGIN";
// export const GET_APPS = "GET_APPS";
// export const OPEN_RELEASES_MODAL = "OPEN_RELEASES_MODAL";
// export const CLOSE_RELEASES_MODAL = "CLOSE_RELEASES_MODAL";
const ActionTypes = keyMirror({
LOGIN: null,
GET_APPS: null,
OPEN_RELEASES_MODAL: null,
CLOSE_RELEASES_MODAL: null,
GET_RELEASE: null
});
export default ActionTypes;

@ -1,17 +1,34 @@
import {GET_APPS} from "../constants/action-types"; import ActionTypes from "../constants/ActionTypes";
const initialState = { const initialState = {
apps: [] apps: [],
releaseView: {
visible: false,
app: null
},
release: null
}; };
function rootReducer(state = initialState, action) { function rootReducer(state = initialState, action) {
if (action.type === GET_APPS) { if (action.type === ActionTypes.GET_APPS) {
console.log(11);
return Object.assign({}, state, { return Object.assign({}, state, {
apps: action.payload apps: action.payload
}); });
} else if (action.type === ActionTypes.OPEN_RELEASES_MODAL) {
return Object.assign({}, state, {
releaseView: {
visible: true,
app: action.payload.app
}
});
}else if(action.type === ActionTypes.GET_RELEASE){
return Object.assign({}, state, {
release: action.payload
});
} }
return state; return state;
} }
export default rootReducer; export default rootReducer;

@ -1,7 +1,8 @@
import React from "react"; import React from "react";
import "antd/dist/antd.css"; import "antd/dist/antd.css";
import {PageHeader, Typography,Input, Button, Row, Col} from "antd"; import {PageHeader, Typography,Input, Button, Row, Col} from "antd";
import AppList from "../../../components/AppList"; import AppList from "../../../components/apps/AppList";
import ReleaseModal from "../../../components/apps/ReleaseModal";
const Search = Input.Search; const Search = Input.Search;
@ -46,6 +47,7 @@ class Apps extends React.Component {
<Button style={{margin:5}}>Advanced Search</Button> <Button style={{margin:5}}>Advanced Search</Button>
</Col> </Col>
</Row> </Row>
<ReleaseModal/>
<AppList/> <AppList/>
</div> </div>

@ -0,0 +1,80 @@
import React from "react";
import {PageHeader, Typography, Input, Button, Row, Col, Avatar, Card} from "antd";
import {connect} from "react-redux";
import ReleaseView from "../../../../components/apps/release/ReleaseView";
import {getRelease} from "../../../../js/actions";
const Search = Input.Search;
const {Title} = Typography;
const routes = [
{
path: 'index',
breadcrumbName: 'Publisher',
},
{
path: 'first',
breadcrumbName: 'Dashboard',
},
{
path: 'second',
breadcrumbName: 'Apps',
},
];
const mapStateToProps = state => {
return {release: state.release}
};
const mapDispatchToProps = dispatch => ({
getRelease: (uuid) => dispatch(getRelease(uuid))
});
class ConnectedRelease extends React.Component {
routes;
constructor(props) {
super(props);
this.routes = props.routes;
}
componentDidMount() {
const {uuid} = this.props.match.params;
this.props.getRelease(uuid);
}
render() {
const release = this.props.release;
if (release == null) {
return (
<div style={{background: '#f0f2f5', padding: 24, minHeight: 780}}>
<Title level={3}>No Releases Found</Title>
</div>
);
}
return (
<div>
<PageHeader
breadcrumb={{routes}}
/>
<div style={{background: '#f0f2f5', padding: 24, minHeight: 780}}>
<Row style={{padding: 10}}>
<Col span={18}>
<Card>
<ReleaseView release={release}/>
</Card>
</Col>
</Row>
</div>
</div>
);
}
}
const Release = connect(mapStateToProps,mapDispatchToProps)(ConnectedRelease);
export default Release;
Loading…
Cancel
Save