mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Merge branch 'application-mgt-new' of gitlab.com:entgra/carbon-device-mgt into application-mgt-new
This commit is contained in:
commit
3a5cf16c26
@ -16,10 +16,11 @@
|
|||||||
"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",
|
||||||
|
"react-router": "latest",
|
||||||
"react-router-config": "^5.0.0",
|
"react-router-config": "^5.0.0",
|
||||||
"react-router-dom": "latest",
|
"react-router-dom": "latest",
|
||||||
"react-scripts": "2.1.8",
|
"react-scripts": "2.1.8",
|
||||||
"react-router": "latest"
|
"redux-thunk": "^2.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.0.0",
|
"@babel/core": "^7.0.0",
|
||||||
@ -37,6 +38,7 @@
|
|||||||
"html-loader": "^0.5.5",
|
"html-loader": "^0.5.5",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"img-loader": "^3.0.1",
|
"img-loader": "^3.0.1",
|
||||||
|
"json-loader": "^0.5.7",
|
||||||
"less": "^3.9.0",
|
"less": "^3.9.0",
|
||||||
"less-loader": "^4.1.0",
|
"less-loader": "^4.1.0",
|
||||||
"mini-css-extract-plugin": "^0.5.0",
|
"mini-css-extract-plugin": "^0.5.0",
|
||||||
|
|||||||
@ -3,10 +3,16 @@
|
|||||||
"type": "default",
|
"type": "default",
|
||||||
"value": "lightBaseTheme"
|
"value": "lightBaseTheme"
|
||||||
},
|
},
|
||||||
"config": {
|
"serverConfig": {
|
||||||
"hostname": "localhost",
|
"hostname": "localhost",
|
||||||
"httpsPort": "9443",
|
"httpsPort": "9443",
|
||||||
"apiPort": "8243"
|
"invokerUri": "/api/application-mgt-handler/v1.0/invoke",
|
||||||
|
"loginUri": "/api/application-mgt-handler/v1.0/login"
|
||||||
},
|
},
|
||||||
"serverUrl" : "https://localhost:9443"
|
"serverUrl" : "https://localhost:9443",
|
||||||
|
"defaultPlatformIcons": {
|
||||||
|
"default": "http://www.newdesignfile.com/postpic/2015/08/square-app-icon-blue_77131.png",
|
||||||
|
"android": "data:image/png;base64,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",
|
||||||
|
"ios" : "data:image/png;base64,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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,22 +3,28 @@ import "antd/dist/antd.css";
|
|||||||
import RouteWithSubRoutes from "./components/RouteWithSubRoutes";
|
import RouteWithSubRoutes from "./components/RouteWithSubRoutes";
|
||||||
import {
|
import {
|
||||||
BrowserRouter as Router,
|
BrowserRouter as Router,
|
||||||
Link,
|
Link, Redirect, Switch,
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
|
|
||||||
class App extends React.Component {
|
class App extends React.Component {
|
||||||
routes;
|
routes;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.routes = props.routes;
|
this.routes = props.routes;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
console.log(this.routes);
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
<div>
|
<div>
|
||||||
|
<Switch>
|
||||||
|
<Redirect exact from="/publisher" to="/publisher/apps"/>
|
||||||
{this.routes.map((route) => (
|
{this.routes.map((route) => (
|
||||||
<RouteWithSubRoutes key={route.path} {...route} />
|
<RouteWithSubRoutes key={route.path} {...route} />
|
||||||
))}
|
))}
|
||||||
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
</Router>
|
</Router>
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,47 @@
|
|||||||
|
import {
|
||||||
|
Skeleton, Switch, Card, Icon, Avatar, Typography
|
||||||
|
} from 'antd';
|
||||||
|
import React from "react";
|
||||||
|
import config from "../../public/conf/config.json";
|
||||||
|
|
||||||
|
const { Meta } = Card;
|
||||||
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
class AppCard extends React.Component {
|
||||||
|
|
||||||
|
constructor(props){
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const defaultPlatformIcons = config.defaultPlatformIcons;
|
||||||
|
let icon = defaultPlatformIcons.default;
|
||||||
|
if(defaultPlatformIcons.hasOwnProperty(this.props.platform)){
|
||||||
|
icon = defaultPlatformIcons[this.props.platform];
|
||||||
|
}
|
||||||
|
let descriptionText = this.props.description;
|
||||||
|
if(descriptionText.length>50){
|
||||||
|
descriptionText = descriptionText.substring(0,50)+"...";
|
||||||
|
}
|
||||||
|
const description = (
|
||||||
|
<div>
|
||||||
|
<p>{descriptionText}</p>
|
||||||
|
<Text code>{this.props.type}</Text>
|
||||||
|
<Text> {this.props.subType}</Text>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card style={{marginTop: 16 }} actions={[<Icon type="edit" />, <Icon type="close" />, <Icon type="ellipsis" />]}>
|
||||||
|
<Meta
|
||||||
|
avatar={<Avatar src={icon} />}
|
||||||
|
title={this.props.name}
|
||||||
|
description={description}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AppCard;
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
import React from "react";
|
||||||
|
import AppCard from "./AppCard";
|
||||||
|
import {Col, Row} from "antd";
|
||||||
|
import {connect} from "react-redux";
|
||||||
|
import {getApps} from "../js/actions";
|
||||||
|
|
||||||
|
// connecting state.articles with the component
|
||||||
|
const mapStateToProps= state => {
|
||||||
|
return {apps : state.apps}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectedAppList extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.getApps();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Row gutter={16}>
|
||||||
|
{this.props.apps.map(app => (
|
||||||
|
<Col key={app.id} xs={24} sm={12} md={6} lg={6}>
|
||||||
|
<AppCard key={app.id}
|
||||||
|
name={app.name}
|
||||||
|
platform={app.deviceType}
|
||||||
|
type={app.type}
|
||||||
|
subType={app.subType}
|
||||||
|
description={app.description}/>
|
||||||
|
</Col>
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const AppList = connect(mapStateToProps,{getApps})(ConnectedAppList);
|
||||||
|
|
||||||
|
export default AppList;
|
||||||
@ -8,7 +8,7 @@ class RouteWithSubRoutes extends React.Component{
|
|||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
return(
|
return(
|
||||||
<Route path={this.props.path} render={(props) => (
|
<Route path={this.props.path} exact={this.props.exact} render={(props) => (
|
||||||
<this.props.component {...props} routes={this.props.routes}/>
|
<this.props.component {...props} routes={this.props.routes}/>
|
||||||
)}/>
|
)}/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -14,19 +14,23 @@ import {Provider} from "react-redux";
|
|||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: '/publisher/login',
|
path: '/publisher/login',
|
||||||
|
exact: true,
|
||||||
component: Login
|
component: Login
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/publisher',
|
path: '/publisher/apps',
|
||||||
|
exact: false,
|
||||||
component: Dashboard,
|
component: Dashboard,
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/publisher/apps',
|
path: '/publisher/apps',
|
||||||
component: Apps
|
component: Apps,
|
||||||
|
exact: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/publisher/new-app',
|
path: '/publisher/apps/new-app',
|
||||||
component: AddNewApp
|
component: AddNewApp,
|
||||||
|
exact: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import {GET_APPS} from "../constants/action-types";
|
||||||
|
import config from "../../../public/conf/config.json";
|
||||||
|
|
||||||
|
export function getApps() {
|
||||||
|
|
||||||
|
return (dispatch) => {
|
||||||
|
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
|
||||||
|
).then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
let apps = [];
|
||||||
|
|
||||||
|
if(res.data.data.hasOwnProperty("applications")){
|
||||||
|
apps = res.data.data.applications;
|
||||||
|
}
|
||||||
|
console.log(res.data);
|
||||||
|
dispatch({type: GET_APPS, payload: apps});
|
||||||
|
}
|
||||||
|
|
||||||
|
}).catch(function (error) {
|
||||||
|
if (error.response.status === 401) {
|
||||||
|
window.location.href = 'https://localhost:9443/publisher/login';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1 +1,3 @@
|
|||||||
export const LOGIN = "LOGIN";
|
export const LOGIN = "LOGIN";
|
||||||
|
export const GET_APPS = "GET_APPS";
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,16 @@
|
|||||||
const initialState = {
|
import {GET_APPS} from "../constants/action-types";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
apps: []
|
||||||
};
|
};
|
||||||
|
|
||||||
function rootReducer(state = initialState, action) {
|
function rootReducer(state = initialState, action) {
|
||||||
|
if (action.type === GET_APPS) {
|
||||||
|
console.log(11);
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
apps: action.payload
|
||||||
|
});
|
||||||
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { createStore } from "redux";
|
import { createStore, applyMiddleware } from "redux";
|
||||||
import rootReducer from "../reducers/index";
|
import rootReducer from "../reducers/index";
|
||||||
const store = createStore(rootReducer);
|
import thunk from "redux-thunk";
|
||||||
|
const store = createStore(rootReducer, applyMiddleware(thunk));
|
||||||
export default store;
|
export default store;
|
||||||
@ -2,6 +2,7 @@ import React from "react";
|
|||||||
import {Typography, Row, Col, Form, Icon, Input, Button, Checkbox} from 'antd';
|
import {Typography, Row, Col, Form, Icon, Input, Button, Checkbox} from 'antd';
|
||||||
import styles from './Login.less';
|
import styles from './Login.less';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import config from "../../public/conf/config.json";
|
||||||
|
|
||||||
const {Title} = Typography;
|
const {Title} = Typography;
|
||||||
const {Text} = Typography;
|
const {Text} = Typography;
|
||||||
@ -58,7 +59,7 @@ class NormalLoginForm extends React.Component {
|
|||||||
});
|
});
|
||||||
console.log('Received values of form: ', values);
|
console.log('Received values of form: ', values);
|
||||||
let data = "username=" + values.username + "&password=" + values.password + "&platform=publisher";
|
let data = "username=" + values.username + "&password=" + values.password + "&platform=publisher";
|
||||||
axios.post('https://localhost:9443/api/application-mgt-handler/v1.0/login', data
|
axios.post('https://'+config.serverConfig.hostname+':'+config.serverConfig.httpsPort+config.serverConfig.loginUri, data
|
||||||
).then(res => {
|
).then(res => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
window.location = res.data.url;
|
window.location = res.data.url;
|
||||||
|
|||||||
@ -31,14 +31,14 @@ class Dashboard extends React.Component {
|
|||||||
defaultSelectedKeys={['2']}
|
defaultSelectedKeys={['2']}
|
||||||
style={{lineHeight: '64px'}}
|
style={{lineHeight: '64px'}}
|
||||||
>
|
>
|
||||||
<Menu.Item key="1"><Link to="apps"><Icon type="appstore"/>Apps</Link></Menu.Item>
|
<Menu.Item key="1"><Link to="/publisher/apps"><Icon type="appstore"/>Apps</Link></Menu.Item>
|
||||||
<Menu.Item key="2"><Link to="apps"><Icon type="line-chart"/>Apps</Link></Menu.Item>
|
<Menu.Item key="2"><Link to="/publisher/apps"><Icon type="line-chart"/>Apps</Link></Menu.Item>
|
||||||
<Menu.Item key="3"><Link to="new-app"><Icon type="upload"/>Add New App</Link></Menu.Item>
|
<Menu.Item key="3"><Link to="/publisher/apps/new-app"><Icon type="upload"/>Add New App</Link></Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
</Header>
|
</Header>
|
||||||
<Content style={{padding: '0 0'}}>
|
<Content style={{padding: '0 0'}}>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Redirect exact from="/publisher" to="/publisher/apps"/>
|
<Redirect exact from="/publisher/dashboard" to="/publisher/dashboard/apps"/>
|
||||||
{this.state.routes.map((route) => (
|
{this.state.routes.map((route) => (
|
||||||
<RouteWithSubRoutes key={route.path} {...route} />
|
<RouteWithSubRoutes key={route.path} {...route} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import "antd/dist/antd.css";
|
import "antd/dist/antd.css";
|
||||||
import {Table, Divider, Tag, Card, PageHeader, Typography, Avatar,Input, Button, Icon, Row, Col} from "antd";
|
import {PageHeader, Typography,Input, Button, Row, Col} from "antd";
|
||||||
import Highlighter from 'react-highlight-words';
|
import AppList from "../../../components/AppList";
|
||||||
|
|
||||||
const Paragraph = Typography;
|
|
||||||
const Search = Input.Search;
|
const Search = Input.Search;
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
@ -22,176 +21,21 @@ const routes = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const data = [{
|
|
||||||
key: '1',
|
|
||||||
icon: 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png',
|
|
||||||
name: 'John Brown',
|
|
||||||
platform: 'android',
|
|
||||||
type: 'Enterprise',
|
|
||||||
status: 'published',
|
|
||||||
version: '13.0.0.1',
|
|
||||||
updated_at: '27-03-2019 08:27'
|
|
||||||
},{
|
|
||||||
key: '2',
|
|
||||||
icon: 'http://aztechbeat.com/wp-content/uploads/2014/04/confide-app-icon.png',
|
|
||||||
name: 'Lorem Ipsum',
|
|
||||||
platform: 'ios',
|
|
||||||
type: 'Enterprise',
|
|
||||||
status: 'published',
|
|
||||||
version: '2.3.1.2',
|
|
||||||
updated_at: '27-03-2019 09:45'
|
|
||||||
},{
|
|
||||||
key: '3',
|
|
||||||
icon: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRx2Xx1-hnH16EGZHUlT06nOcfGODPoboA2TXKaBVtODto4lJtK',
|
|
||||||
name: 'Lorem Ipsum',
|
|
||||||
platform: 'ios',
|
|
||||||
type: 'Enterprise',
|
|
||||||
status: 'removed',
|
|
||||||
version: '4.1.1.0',
|
|
||||||
updated_at: '27-03-2019 09:46'
|
|
||||||
}];
|
|
||||||
|
|
||||||
class Apps extends React.Component {
|
class Apps extends React.Component {
|
||||||
routes;
|
routes;
|
||||||
|
|
||||||
|
|
||||||
state = {
|
|
||||||
searchText: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.routes = props.routes;
|
this.routes = props.routes;
|
||||||
}
|
|
||||||
|
|
||||||
getColumnSearchProps = (dataIndex) => ({
|
|
||||||
filterDropdown: ({
|
|
||||||
setSelectedKeys, selectedKeys, confirm, clearFilters,
|
|
||||||
}) => (
|
|
||||||
<div style={{ padding: 8 }}>
|
|
||||||
<Input
|
|
||||||
ref={node => { this.searchInput = node; }}
|
|
||||||
placeholder={`Search ${dataIndex}`}
|
|
||||||
value={selectedKeys[0]}
|
|
||||||
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
|
|
||||||
onPressEnter={() => this.handleSearch(selectedKeys, confirm)}
|
|
||||||
style={{ width: 188, marginBottom: 8, display: 'block' }}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
onClick={() => this.handleSearch(selectedKeys, confirm)}
|
|
||||||
icon="search"
|
|
||||||
size="small"
|
|
||||||
style={{ width: 90, marginRight: 8 }}
|
|
||||||
>
|
|
||||||
Search
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
onClick={() => this.handleReset(clearFilters)}
|
|
||||||
size="small"
|
|
||||||
style={{ width: 90 }}
|
|
||||||
>
|
|
||||||
Reset
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
filterIcon: filtered => <Icon type="search" style={{ color: filtered ? '#1890ff' : undefined }} />,
|
|
||||||
onFilter: (value, record) => record[dataIndex].toString().toLowerCase().includes(value.toLowerCase()),
|
|
||||||
onFilterDropdownVisibleChange: (visible) => {
|
|
||||||
if (visible) {
|
|
||||||
setTimeout(() => this.searchInput.select());
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
render: (text) => (
|
|
||||||
<Highlighter
|
|
||||||
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
|
|
||||||
searchWords={[this.state.searchText]}
|
|
||||||
autoEscape
|
|
||||||
textToHighlight={text.toString()}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
|
|
||||||
handleSearch = (selectedKeys, confirm) => {
|
|
||||||
confirm();
|
|
||||||
this.setState({ searchText: selectedKeys[0] });
|
|
||||||
}
|
|
||||||
|
|
||||||
handleReset = (clearFilters) => {
|
|
||||||
clearFilters();
|
|
||||||
this.setState({ searchText: '' });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const columns = [{
|
|
||||||
title: '',
|
|
||||||
dataIndex: 'icon',
|
|
||||||
key: 'icon',
|
|
||||||
render: text => <Avatar size="large" src={text}/>,
|
|
||||||
}, {
|
|
||||||
title: 'Name',
|
|
||||||
dataIndex: 'name',
|
|
||||||
key: 'name',
|
|
||||||
render: text => <a href="javascript:;">{text}</a>,
|
|
||||||
...this.getColumnSearchProps('name'),
|
|
||||||
}, {
|
|
||||||
title: 'Platform',
|
|
||||||
dataIndex: 'platform',
|
|
||||||
key: 'platform',
|
|
||||||
}, {
|
|
||||||
title: 'Type',
|
|
||||||
dataIndex: 'type',
|
|
||||||
key: 'type',
|
|
||||||
}, {
|
|
||||||
title: 'Status',
|
|
||||||
key: 'status',
|
|
||||||
dataIndex: 'status',
|
|
||||||
render: tag => {
|
|
||||||
let color;
|
|
||||||
switch (tag) {
|
|
||||||
case 'published':
|
|
||||||
color = 'green';
|
|
||||||
break;
|
|
||||||
case 'removed':
|
|
||||||
color = 'red'
|
|
||||||
break;
|
|
||||||
case 'default':
|
|
||||||
color = 'blue'
|
|
||||||
}
|
|
||||||
return <Tag color={color} key={tag}>{tag.toUpperCase()}</Tag>;
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
title: 'Published Version',
|
|
||||||
dataIndex: 'version',
|
|
||||||
key: 'version',
|
|
||||||
}, {
|
|
||||||
title: 'Last Updated',
|
|
||||||
dataIndex: 'updated_at',
|
|
||||||
key: 'updated_at',
|
|
||||||
},{
|
|
||||||
title: 'Action',
|
|
||||||
key: 'action',
|
|
||||||
render: () => (
|
|
||||||
<span>
|
|
||||||
<a href="javascript:;">Edit</a>
|
|
||||||
<Divider type="vertical" />
|
|
||||||
<a href="javascript:;">Manage</a>
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
}];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
breadcrumb={{routes}}
|
breadcrumb={{routes}}
|
||||||
/>
|
/>
|
||||||
<div style={{background: '#f0f2f5', padding: 24, minHeight: 780}}>
|
<div style={{background: '#f0f2f5', padding: 24, minHeight: 780}}>
|
||||||
|
|
||||||
<Card>
|
|
||||||
<Row style={{padding:10}}>
|
<Row style={{padding:10}}>
|
||||||
<Col span={6} offset={18}>
|
<Col span={6} offset={18}>
|
||||||
<Search
|
<Search
|
||||||
@ -202,8 +46,7 @@ class Apps extends React.Component {
|
|||||||
<Button style={{margin:5}}>Advanced Search</Button>
|
<Button style={{margin:5}}>Advanced Search</Button>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Table columns={columns} dataSource={data}/>
|
<AppList/>
|
||||||
</Card>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -0,0 +1,226 @@
|
|||||||
|
import React from "react";
|
||||||
|
import "antd/dist/antd.css";
|
||||||
|
import {Table, Divider, Tag, Card, PageHeader, Typography, Avatar,Input, Button, Icon, Row, Col} from "antd";
|
||||||
|
import Highlighter from 'react-highlight-words';
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
const Paragraph = Typography;
|
||||||
|
const Search = Input.Search;
|
||||||
|
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
path: 'index',
|
||||||
|
breadcrumbName: 'Publisher',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'first',
|
||||||
|
breadcrumbName: 'Dashboard',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'second',
|
||||||
|
breadcrumbName: 'OldApps',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
class OldApps extends React.Component {
|
||||||
|
routes;
|
||||||
|
|
||||||
|
state = {
|
||||||
|
searchText: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.routes = props.routes;
|
||||||
|
this.state = {
|
||||||
|
data: []
|
||||||
|
};
|
||||||
|
|
||||||
|
this.loadData = this.loadData.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadData(){
|
||||||
|
const thisComponent = this;
|
||||||
|
const request = "method=post&content-type=application/json&payload={}&api-endpoint=/application-mgt-publisher/v1.0/applications";
|
||||||
|
axios.post('https://localhost:9443/api/application-mgt-handler/v1.0/invoke', request
|
||||||
|
).then(res => {
|
||||||
|
if(res.status === 200){
|
||||||
|
console.log(res.status);
|
||||||
|
let apps = [];
|
||||||
|
res.data['data']['applications'].forEach(function (app) {
|
||||||
|
apps.push({
|
||||||
|
key: app.id,
|
||||||
|
icon: app["applicationReleases"][0]["iconPath"],
|
||||||
|
name: app.name,
|
||||||
|
platform: 'undefined',
|
||||||
|
type: app.type,
|
||||||
|
status: 'undefined',
|
||||||
|
version: 'undefined',
|
||||||
|
updated_at: 'undefined'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
thisComponent.setState({
|
||||||
|
data : apps
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}).catch(function (error) {
|
||||||
|
if(error.response.status === 401){
|
||||||
|
window.location.href = 'https://localhost:9443/publisher/login';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.loadData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getColumnSearchProps = (dataIndex) => ({
|
||||||
|
filterDropdown: ({
|
||||||
|
setSelectedKeys, selectedKeys, confirm, clearFilters,
|
||||||
|
}) => (
|
||||||
|
<div style={{ padding: 8 }}>
|
||||||
|
<Input
|
||||||
|
ref={node => { this.searchInput = node; }}
|
||||||
|
placeholder={`Search ${dataIndex}`}
|
||||||
|
value={selectedKeys[0]}
|
||||||
|
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
|
||||||
|
onPressEnter={() => this.handleSearch(selectedKeys, confirm)}
|
||||||
|
style={{ width: 188, marginBottom: 8, display: 'block' }}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={() => this.handleSearch(selectedKeys, confirm)}
|
||||||
|
icon="search"
|
||||||
|
size="small"
|
||||||
|
style={{ width: 90, marginRight: 8 }}
|
||||||
|
>
|
||||||
|
Search
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => this.handleReset(clearFilters)}
|
||||||
|
size="small"
|
||||||
|
style={{ width: 90 }}
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
filterIcon: filtered => <Icon type="search" style={{ color: filtered ? '#1890ff' : undefined }} />,
|
||||||
|
onFilter: (value, record) => record[dataIndex].toString().toLowerCase().includes(value.toLowerCase()),
|
||||||
|
onFilterDropdownVisibleChange: (visible) => {
|
||||||
|
if (visible) {
|
||||||
|
setTimeout(() => this.searchInput.select());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render: (text) => (
|
||||||
|
<Highlighter
|
||||||
|
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
|
||||||
|
searchWords={[this.state.searchText]}
|
||||||
|
autoEscape
|
||||||
|
textToHighlight={text.toString()}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
handleSearch = (selectedKeys, confirm) => {
|
||||||
|
confirm();
|
||||||
|
this.setState({ searchText: selectedKeys[0] });
|
||||||
|
};
|
||||||
|
|
||||||
|
handleReset = (clearFilters) => {
|
||||||
|
clearFilters();
|
||||||
|
this.setState({ searchText: '' });
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const columns = [{
|
||||||
|
title: '',
|
||||||
|
dataIndex: 'icon',
|
||||||
|
key: 'icon',
|
||||||
|
render: text => <Avatar size="large" src={text}/>,
|
||||||
|
}, {
|
||||||
|
title: 'Name',
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name',
|
||||||
|
render: text => <a href="javascript:;">{text}</a>,
|
||||||
|
...this.getColumnSearchProps('name'),
|
||||||
|
}, {
|
||||||
|
title: 'Platform',
|
||||||
|
dataIndex: 'platform',
|
||||||
|
key: 'platform',
|
||||||
|
}, {
|
||||||
|
title: 'Type',
|
||||||
|
dataIndex: 'type',
|
||||||
|
key: 'type',
|
||||||
|
}, {
|
||||||
|
title: 'Status',
|
||||||
|
key: 'status',
|
||||||
|
dataIndex: 'status',
|
||||||
|
render: tag => {
|
||||||
|
let color;
|
||||||
|
switch (tag) {
|
||||||
|
case 'published':
|
||||||
|
color = 'green';
|
||||||
|
break;
|
||||||
|
case 'removed':
|
||||||
|
color = 'red';
|
||||||
|
break;
|
||||||
|
case 'default':
|
||||||
|
color = 'blue';
|
||||||
|
}
|
||||||
|
return <Tag color={color} key={tag}>{tag.toUpperCase()}</Tag>;
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
title: 'Published Version',
|
||||||
|
dataIndex: 'version',
|
||||||
|
key: 'version',
|
||||||
|
}, {
|
||||||
|
title: 'Last Updated',
|
||||||
|
dataIndex: 'updated_at',
|
||||||
|
key: 'updated_at',
|
||||||
|
},{
|
||||||
|
title: 'Action',
|
||||||
|
key: 'action',
|
||||||
|
render: () => (
|
||||||
|
<span>
|
||||||
|
<a href="javascript:;">Edit</a>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<a href="javascript:;">Manage</a>
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
}];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<PageHeader
|
||||||
|
breadcrumb={{routes}}
|
||||||
|
/>
|
||||||
|
<div style={{background: '#f0f2f5', padding: 24, minHeight: 780}}>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<Row style={{padding:10}}>
|
||||||
|
<Col span={6} offset={18}>
|
||||||
|
<Search
|
||||||
|
placeholder="search"
|
||||||
|
onSearch={value => console.log(value)}
|
||||||
|
style={{ width: 200}}
|
||||||
|
/>
|
||||||
|
<Button style={{margin:5}}>Advanced Search</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Table columns={columns} dataSource={this.state.data}/>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OldApps;
|
||||||
Loading…
Reference in New Issue
Block a user